2012-07-23 27 views
3

我一直在這篇文章下面,http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx實體框架 - 故障與.Load()

具體標題爲「應用過濾器加載明確相關實體的時候」。

我需要做的是這樣的:當我通過這一步

db.Configuration.LazyLoadingEnabled = false; 
var class = db.Classes.Find(1); 
db.Entry(class).Collection(c => c.Students).Query().Where(s => s.grade > 2.0).Load(); 

,看SQL事件探查我看到加載類的查詢。然後我看到應該加載學生,但類的查詢。學生從未填充,並保持空。但是,如果我從SQL分析器中複製學生查詢並在自己中運行,則會返回相應的學生。看來,實體框架正在運行學生查詢並獲得正確的結果,但沒有將它們附加到類對象。

有辦法我可以解決這個問題,但我想知道如果我錯過了一個步驟,或者如果我沒有正確使用.Load()。

回答

2

如果ClassStudent之間的關係是一個許多一對多關係,你看到的是預期的行爲(儘管混亂,我承認)。首先,如果你看過智能感知說怎麼樣Load方法...

枚舉查詢,使得服務器的查詢,如那些 System.Data.Entity.DbSet, System.Data.Objects的.ObjectSet, System.Data.Objects.ObjectQuery等 查詢的結果將被加載到關聯的System.Data.Entity.DbContext, System.Data.Objects.ObjectContext或客戶端上的其他緩存 。這個 相當於調用ToList,然後扔掉列表 ,而沒有實際創建列表的開銷。

...它沒有說,實體的導航集運行與被填充的查詢,只有結果被加載到上下文。

當您調用Load是不是真的這個方法,但所謂關係跨度或修復行動方面的後續處理結果中的一個一對多關係情況下,導航集合填充,這種處理不會發生在多對多的關係中。

在這個問題的答案是更多的細節:EF 4.1 loading filtered child collections not working for many-to-many

的精髓在於 - 對於許多一對多的關係 - 你必須直接使用ToList()代替Load()填充導航集合:

var class1 = db.Classes.Find(1); 
class1.Students = db.Entry(class1).Collection(c => c.Students).Query() 
    .Where(s => s.grade > 2.0).ToList(); 

這會將學生加載到上下文中同時在class1中填充導航集合。