EF急切加载和延迟加载的区别?

Posted

技术标签:

【中文标题】EF急切加载和延迟加载的区别?【英文标题】:EF difference in eager loading and lazy loading? 【发布时间】:2012-06-04 08:34:25 【问题描述】:

我是 EF 新手,已经阅读了一些文章。阅读后,我对延迟加载和急切加载之间的区别感到困惑?

可以编译这两种类型的查询吗? 两种类型的查询都可以返回IQuerableIEnumerable吗? 两种类型的查询都可以有 Linq to Entities 查询语法(select、from、where)和 lambda 表达式吗?

请指导和帮助我。

非常感谢您的时间和指导

【问题讨论】:

Lazy loading, Deferred Loading and Eager Loading in Entity framework 的可能重复项 我认为在您的查询中使用.Include 可以立即加载,也许您可​​以通过使用它来控制 【参考方案1】:

关于lazyeager加载的区别:

假设您有一个 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急切加载和延迟加载的区别?的主要内容,如果未能解决你的问题,请参考以下文章

我可以同时使用急切和延迟加载吗?

何时在休眠中使用延迟加载/急切加载?

延迟加载孩子,里面有急切的集合

远程案例中的延迟/急切加载策略(JPA)

LINQ中的First()会导致急切或延迟加载吗?

Xamarin Forms Shell - 一次加载每个选项卡 - 急切加载而不是延迟加载