2011-11-11 209 views
2

我正在使用POCO对象实体框架,并且已启用LazyLoading。实体框架4延迟加载实体集

如果我正在处理与对象关联的集合,集合何时完全加载以及在什么情况下?

如果我把每一种

Order.OrderItems.Count() 
Order.OrderItems.Any(x => x.StatusId = aValue) 
Order.OrderItems.All(x => x.StatusId = aValue) 

做这些保证的OrderItems收集的完整加载? 在代码中的点查询

后查询或

context.LoadProperty(order, “OrderItems”) 

,当我们呼吁

Order.Include(“OrderItems”) 

但我已经意识到有时这并不总是发生 - 我想知道这不会发生的后果。我觉得我有一点与它

回答

4

LINQ的方法知识差距一般不会加载数据,直到您foreach在他们的结果,或追加ToListToArray,等等。这是如何LINQ到实体提供者可以允许您链接方法并仅在最终结构上构建查询。

如果某个方法返回IQueryableIEnumerable,那么您可以确信Linq在此时不会加载数据。

但是:

Order.OrderItems.Count() 
Order.OrderItems.Any(x => x.StatusId = aValue) 
Order.OrderItems.All(x => x.StatusId = aValue) 

对于最外侧的查询,如果LINQ的必须返回一个布尔值或整数,那么它必须立即执行查询。但是对于嵌套查询,事情会变得更复杂一些,因为直到外部查询被评估为止,它们才会被评估。

至于:

Order.Include("OrderItems") 

我相信一个Include不会自行解决的查询。当您进行另一个查询时,您可以使用它来搭载额外的数据。

LINQ的一般

如果您想了解(一般)的LINQ是如何工作的,你可以看看这组文章:

http://msmvps.com/blogs/jon_skeet/archive/tags/Edulinq/default.aspx

这会给你的想法当IEnumerable可以推迟,以及何时必须评估。它不会告诉你关于Linq to Entities提供者的所有信息,但很大一部分知识会转移。

+0

谢谢@Merlyn Morgan-Graham。 你能澄清'如果Linq必须返回一个布尔值或整数,那么它很可能立即运行你的查询'。我查看了http://msmvps.com/blogs/jon_skeet/archive/2010/12/28/reimplementing-linq-to-objects-part-10-any-and-all.aspx,看起来Any和所有实际上遍历覆盖下的结果,所以会自动实现收集。因此,看起来好像任何/全部都会在外部查询中加载集合 –

+1

@TimBrown:“看起来Any和All实际上遍历了封面下的结果,因此会自动实现集合”。我想这正是我所说的,只是在鼬鼠说话(“可能”= **总是**,哈哈)。我刚刚做了一个编辑,希望能够澄清这句话。 –

+0

另外,通过嵌套查询,我的意思是:'Order.OrderItems.Where(i => i.Rebates.Any())'''Rebates.Any()'不会被评估,除非外部查询是评估。 –

3
Order.OrderItems.Any(x => x.StatusId = aValue) 
Order.OrderItems.All(x => x.StatusId = aValue) 

是查询。

当您调用.ToList()(或某个其他迭代器将其物化为对象)时,会执行这些查询。如果您使用.Include,则在执行查询时,包含的属性将被填充(查询将包含该表的连接)。使用AnyAll(或任何类似Where的过滤器扩展名)只会添加where条件(可能来自另一个表),但它不会将OrderItems放入sql select,因此除非使用.Include,否则它们将不会被加载。

-

不相关的问题,但如果你是这个新鲜的,你有分页,记得打电话ToList(执行查询)之前加入SkipTake您的查询,我所看到的人在进行分页之前很早就调用ToList并将整个表读入内存。

+0

+1为分页建议。真?我想在尝试实现分页时,人们会特别寻找诸如“Skip”和“Take”之类的东西。这就是Linq的全部重点。奇怪...... :) –

+0

好吧,通常没有规范,当人们制作原型时,会出现“分页不可用”指令。后来,该原型变成了发布版本,并且在有xx记录之后,有一条指令将“添加分页”作为“网格占用太多空间”。不知道linq如何在底层工作的新开发人员通常只会将Skip/Take添加到他们在控制器/代码隐藏的变量中,而不知道包含整个表的变量。这是linq错误使用中出现的最简单的性能问题(想象一下foreach循环中的“subquery”:))。 –

+0

感谢您的评论@Goran Obradovic,但您的评论'这些查询是在您调用.ToList()'时执行的,似乎与第一个答案相矛盾,该答案表示返回布尔型或int型的方法将加载该集合。道歉,如果我误解了。有矛盾吗? –

相关问题