我们所有的导航属性都被定义为虚拟(延迟加载),但大多数都是急切加载的(.Include)是否存在延迟加载灵活性的性能影响?当我们真正需要延迟加载时,我们应该只是延迟加载吗?
感谢。
答案 0 :(得分:2)
快速基准测试(在对象图中加载数千个对象)表明,在启用或禁用延迟加载和代理生成时,加载时间没有明显差异。
但是,当您知道自己急切加载(并且可能使用短暂的上下文)时,我总是会关闭延迟加载和代理生成。
context.Configuration.LazyLoadingEnabled = false;
context.Configuration.ProxyCreationEnabled = false;
即使它没有显着提高性能,但至少它消除了当上下文超出范围时触发延迟加载的风险,或者当对象被序列化时延迟了延迟加载级联。
在您的情况下,当急切加载时,您甚至可以将其设为默认值,即在构造函数中转换上下文类。
请注意,在使用 AsNoTracking()
获取对象时,您确实可以获得性能,当您以只读方式获取对象时,这是一种很好的做法。这经常发生:在断开连接的设置中,例如当对象被序列化到Web客户端时,即使客户端可能能够修改对象,上载也始终是只读的。这些变化将在后期行动中处理。
答案 1 :(得分:0)
这取决于您使用返回的对象的原因。当您尝试访问导航属性时,延迟加载将导致新查询被发送到数据库。
如果您急切地加载对象以包含其所有的导航属性,然后从不使用它们,那么它们是。您正在从数据库请求更多数据,然后需要花费更多时间来解析它们。当然反过来也是如此。
如果从数据库中获取对象并开始访问导航属性,则必须在数据库中查询它们,从而导致发生n + 1个查询。我会说这比批量请求记录更昂贵,但它实际上取决于你知道对象将如何用于特定操作。
就个人而言,在网络环境中,由于上下文很短暂,我急于加载。在桌面环境中,您将为整个应用程序会话保持上下文的活动状态,我会使用延迟加载,因为您不必为后续查询反复构建上下文。