2011-11-11 182 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型的方法將加載該集合。道歉,如果我誤解了。有矛盾嗎? –

相關問題