将导航属性声明为延迟加载但是急于加载它。不好的做法?

时间:2014-01-30 22:13:41

标签: c# performance entity-framework lazy-loading eager-loading

我们所有的导航属性都被定义为虚拟(延迟加载),但大多数都是急切加载的(.Include)是否存在延迟加载灵活性的性能影响?当我们真正需要延迟加载时,我们应该只是延迟加载吗?

感谢。

2 个答案:

答案 0 :(得分:2)

快速基准测试(在对象图中加载数千个对象)表明,在启用或禁用延迟加载和代理生成时,加载时间没有明显差异。

但是,当您知道自己急切加载(并且可能使用短暂的上下文)时,我总是会关闭延迟加载和代理生成。

context.Configuration.LazyLoadingEnabled = false;
context.Configuration.ProxyCreationEnabled = false;

即使它没有显着提高性能,但至少它消除了当上下文超出范围时触发延迟加载的风险,或者当对象被序列化时延迟了延迟加载级联。

在您的情况下,当急切加载时,您甚至可以将其设为默认值,即在构造函数中转换上下文类。

请注意,在使用 AsNoTracking() 获取对象时,您确实可以获得性能,当您以只读方式获取对象时,这是一种很好的做法。这经常发生:在断开连接的设置中,例如当对象被序列化到Web客户端时,即使客户端可能能够修改对象,上载也始终是只读的。这些变化将在后期行动中处理。

答案 1 :(得分:0)

这取决于您使用返回的对象的原因。当您尝试访问导航属性时,延迟加载将导致新查询被发送到数据库。

如果您急切地加载对象以包含其所有的导航属性,然后从不使用它们,那么它们是。您正在从数据库请求更多数据,然后需要花费更多时间来解析它们。当然反过来也是如此。

如果从数据库中获取对象并开始访问导航属性,则必须在数据库中查询它们,从而导致发生n + 1个查询。我会说这比批量请求记录更昂贵,但它实际上取决于你知道对象将如何用于特定操作。

就个人而言,在网络环境中,由于上下文很短暂,我急于加载。在桌面环境中,您将为整个应用程序会话保持上下文的活动状态,我会使用延迟加载,因为您不必为后续查询反复构建上下文。