C# 急切加载和惰性加载的EF差异?

C# 急切加载和惰性加载的EF差异?,c#,.net,entity-framework-4,C#,.net,Entity Framework 4,我是EF的新手,读过一些文章。阅读之后,我弄不明白懒惰加载和急切加载的区别是什么 两种类型的查询都可以编译吗 这两种类型的查询是否都可以返回IQuerable和IEnumerable 这两种类型的查询是否都可以使用Linq到实体查询syntex(select、from、where)和lambda表达式 请引导和帮助我 非常感谢您的时间和指导关于懒惰和渴望加载之间的区别: 假设您有一个Customer对象,该对象具有一个属性List Invoices(该属性位于不同的表中,并由实体框架自动连接

我是EF的新手,读过一些文章。阅读之后,我弄不明白懒惰加载和急切加载的区别是什么

  • 两种类型的查询都可以编译吗
  • 这两种类型的查询是否都可以返回
    IQuerable
    IEnumerable
  • 这两种类型的查询是否都可以使用Linq到实体查询syntex(select、from、where)和lambda表达式
请引导和帮助我


非常感谢您的时间和指导

关于懒惰渴望加载之间的区别:

假设您有一个
Customer
对象,该对象具有一个属性
List Invoices
(该属性位于不同的表中,并由实体框架自动连接)

使用
lazy
加载发票不会在实例化客户对象时立即提取,而是仅在您明确需要/访问它时提取

使用
eager
加载,您的发票将被立即提取并在对象上构建/填充(如果您构建了一个庞大的客户列表,但实际上并不需要在对象上随时提供所有发票,则会带来一些不必要的性能开销)


您将找到一些文档。

关于惰性渴望加载之间的区别:

假设您有一个
Customer
对象,该对象具有一个属性
List Invoices
(该属性位于不同的表中,并由实体框架自动连接)

使用
lazy
加载发票不会在实例化客户对象时立即提取,而是仅在您明确需要/访问它时提取

使用
eager
加载,您的发票将被立即提取并在对象上构建/填充(如果您构建了一个庞大的客户列表,但实际上并不需要在对象上随时提供所有发票,则会带来一些不必要的性能开销)


您可以找到一些文档。

延迟加载只是在实际需要的时候加载相关对象,而快速加载恰恰相反。策略的选择可能会对性能产生很大影响,例如,在您实际上不需要数据集时加载一个大数据集

延迟加载只是在实际需要时加载相关对象,而快速加载则恰恰相反。策略的选择可能会对性能产生很大影响,例如,在您实际上不需要数据集时加载一个大数据集

两种类型的查询都可以编译吗

手动预编译的查询只能包含即时加载。延迟加载查询是由EF自动创建的,如果它实际预编译它,则它是EF的内部行为

这两种类型的查询都可以返回IQuerable和IEnumerable吗

在即时加载中,您可以控制查询是否返回
IQueryable
IEnumerable
。延迟加载查询发生在您无法控制的情况下,您无法对其进行修改。如果要对延迟加载的导航属性使用
IQueryable
,则必须使用第三个名为显式加载的选项,在该选项中,您可以对给定的导航属性进行
IQueryable
查询,并对其进行修改

两种类型的查询是否都具有Linq到实体查询语法(选择, 来自,在哪里)和lambda表达式

否。这两个查询都没有select、from、where。延迟加载发生在您无法控制的情况下,而急切加载不允许过滤——在这两种情况下,您总是加载所有相关对象

显式查询示例(可以使用查询的唯一加载类型):

var query=((EntityCollection)parent.Children.CreateSourceQuery()
.其中(…);
两种类型的查询都可以编译吗

手动预编译的查询只能包含即时加载。延迟加载查询是由EF自动创建的,如果它实际预编译它,则它是EF的内部行为

这两种类型的查询都可以返回IQuerable和IEnumerable吗

在即时加载中,您可以控制查询是否返回
IQueryable
IEnumerable
。延迟加载查询发生在您无法控制的情况下,您无法对其进行修改。如果要对延迟加载的导航属性使用
IQueryable
,则必须使用第三个名为显式加载的选项,在该选项中,您可以对给定的导航属性进行
IQueryable
查询,并对其进行修改

两种类型的查询是否都具有Linq到实体查询语法(选择, 来自,在哪里)和lambda表达式

否。这两个查询都没有select、from、where。延迟加载发生在您无法控制的情况下,而急切加载不允许过滤——在这两种情况下,您总是加载所有相关对象

显式查询示例(可以使用查询的唯一加载类型):

var query=((EntityCollection)parent.Children.CreateSourceQuery()
.其中(…);

+1准确地说,这意味着如果你不小心的话,你可能会遇到N+1问题:你得到
Customer
对象,然后你想迭代
发票。这意味着您将为客户向DB打一个电话,为所有发票打N个电话,因为它们是一个接一个地提取的。这时,您可以在原始查询中
包含
发票
,以便在一次DB调用中急切地获取它们。+1准确地说,这意味着——如果您不小心的话——您可能会遇到N+1问题:您获取
客户
对象,然后希望迭代
发票
。这意味着您将为客户向DB打一个电话,为所有发票打N个电话,因为它们是一个接一个地提取的。此时,您可以在原始查询中
包含
发票
,以便
var query = ((EntityCollection<MyEntity>)parent.Children).CreateSourceQuery()
                                                         .Where(...);