【发布时间】:2014-12-05 14:38:43
【问题描述】:
我正在处理的一个项目有 DbContext,它可以跟踪许多不同的实体。由于涉及大量关系,因此在生成视图时第一次从上下文中查询需要很长时间。为了减少启动时间,并更好地将上下文组织成功能区域,我正在寻找将其分开的方法。
这些是我迄今为止尝试过的一些方法,以及我遇到的问题:
- 使用来自巨大上下文的 DbSet 子集创建一个新的较小上下文。
这无济于事,因为 EF 似乎爬过所有导航属性并包含所有相关实体(至少根据 LINQPad,当它在连接面板中展开时显示与上下文相关的所有实体)。我们有一些影响深远的顶级实体,因此很少有子集可以在不移除导航属性和进行大量重构的情况下完全隔离。
- 将实体拆分为包含导航属性的类和仅包含 db 字段的类,如下所示:
public class PersonLight
{
public int Id { get; set; }
public string Name { get; set; }
public int JobId { get; set; }
}
public class Person : PersonLight
{
public Job Job { get; set; }
}
public class ContextLight : DbContext
{
public virtual DbSet<PersonLight> People { get; set; }
}
这里也没有骰子。即使 Person 根本没有被使用,EF(或者可能只是 LINQPad)包括Person,尽管它不能被使用。我认为这是因为 EF 支持继承模式,所以它也结束了在这个方向上爬取相关实体。
- 与#2 一样,但在不同的项目中使用
PersonLight和Person(或在不同的项目中使用partial类)。这是迄今为止最好的选择,但最好将PersonFields放在Person旁边以方便参考。
所以我的问题是:
- 有没有我想念的更好的方法来做到这一点?
- 为什么,在#3 中,将它们放在不同的项目中似乎足以将它们分开,以至于 EF 不会尝试将两者都包含在内?我尝试将它们放在不同的命名空间中,但这并没有成功。
谢谢。
【问题讨论】:
-
您的数据上下文有多大?我第一次从未经历过任何明显的延迟(我有大约一百个表),我认为您尝试创建实体的“轻量级”版本或“部分”数据上下文根本不是正确的方法。您使用什么分析技术来确定数据上下文和/或实体的大小是罪魁祸首?
-
@KirkWoll 令人尴尬的大...推动 800 个 DbSet。分析总是指向视图生成,我们已经看到通过预生成视图和 EF 更新获得了不错的性能提升,特别提到了该领域的性能改进。在视图被缓存后,后续查询几乎都是即时的。我很乐意听取其他建议。
-
LinqPad 生成它自己的 DBContext (以及其他东西),你无法阻止它,我已经看到了。在 LinqPad 中测试这种东西是行不通的。但是,即使您将 800 个表拆分为 80 个表的 10 个上下文,Linq 仍然需要完成所有初始化工作,因此总体上不会节省时间。但是,它可能会延迟初始化,直到第一次创建特定的上下文,这会使事情变得更顺利。但是,出于您所说的原因,我不喜欢这个想法。
-
它似乎确实有一个每个上下文的初始化过程。这只是为了节省开发时间,因为生产应用程序本身应该不经常重新启动/重新生成视图。如果有人在修改 -> 编译 -> 查看周期中只使用一个较小的上下文,那肯定会更快。我们看到 30 到 90 秒的初始化时间真的会阻碍应该快速的变化。
标签: c# entity-framework entity-framework-6 linqpad