EF急切加载和延迟加载的区别?
Posted
技术标签:
【中文标题】EF急切加载和延迟加载的区别?【英文标题】:EF difference in eager loading and lazy loading? 【发布时间】:2012-06-04 08:34:25 【问题描述】:我是 EF 新手,已经阅读了一些文章。阅读后,我对延迟加载和急切加载之间的区别感到困惑?
可以编译这两种类型的查询吗? 两种类型的查询都可以返回IQuerable
和IEnumerable
吗?
两种类型的查询都可以有 Linq to Entities 查询语法(select、from、where)和 lambda 表达式吗?
请指导和帮助我。
非常感谢您的时间和指导
【问题讨论】:
Lazy loading, Deferred Loading and Eager Loading in Entity framework 的可能重复项 我认为在您的查询中使用.Include
可以立即加载,也许您可以通过使用它来控制
【参考方案1】:
关于lazy和eager加载的区别:
假设您有一个 Customer
对象,该对象具有一个属性 List<Invoice> Invoices
(它位于不同的表中并由实体框架自动连接)。
使用lazy
加载发票不会在您的客户对象被实例化时立即获取,但只有在您需要它/明确访问它时才会获取。
通过eager
加载,您的发票将被立即获取并构造/填充到对象上(如果您构建大量客户列表但并不真正需要所有发票都可以随时使用,这会引入一些不必要的性能开销对象)。
你会发现一些文档here。
【讨论】:
+1 没错,这意味着 - 如果你不小心 - 你可能会遇到 N+1 问题:你得到了Customer
对象,然后你想遍历 @987654327 @。这意味着您将为客户调用 1 次数据库,并为所有发票调用 N 次,因为它们是一个接一个地获取的。那时你 Include
Invoices
在原始查询中急切地在一个数据库调用中获取它们。【参考方案2】:
两种类型的查询都可以编译吗?
只有预先加载才能成为手动预编译查询的一部分。延迟加载查询由 EF 自动创建,如果它实际预编译它是 EF 内部行为。
这两种类型的查询都可以返回 IQuerable 和 IEnumerable 吗?
在预加载中,您可以控制查询返回IQueryable
还是IEnumerable
。延迟加载查询超出您的控制范围,您无法修改它。如果您想将IQueryable
用于延迟加载的导航属性,您必须使用称为显式加载的第三个选项,您可以在其中获取IQueryable
对给定导航属性的查询,您可以对其进行修改。
两种类型的查询都可以具有 Linq 到实体查询语法(选择、 from, where) 和 lambda 表达式?
没有。这些查询都没有 select、from、where。延迟加载超出了您的控制范围,并且急切加载不允许过滤 - 在这两种情况下,您总是会加载所有相关对象。
显式查询示例(唯一可以使用查询的加载类型):
var query = ((EntityCollection<MyEntity>)parent.Children).CreateSourceQuery()
.Where(...);
【讨论】:
【参考方案3】:延迟加载只是在实际需要的时候加载相关的对象,而急切加载则相反。策略的选择可能会对性能产生很大影响,例如当您实际上不需要它时加载一个大数据集。
【讨论】:
以上是关于EF急切加载和延迟加载的区别?的主要内容,如果未能解决你的问题,请参考以下文章