0

我正在用實體框架5編寫C#(.NET 4.5)中的簡單數據庫應用程序。我遇到了一種情況,我可能或可能不需要加載單個實體的相關實體。如果碰巧需要加載實體的相關實體,我想急於加載相關實體的相關實體。基本上,我試圖避免「SELECT N + 1」問題。希望下面的代碼將使我想要做的事情明確:實體框架 - 渴望加載相關實體的相關實體

using (var ctx = new DbContext()) 
{ 
    // Find a single instance of a person. I don't want to eagerly load 
    // the person's friends at this point because I may not need this 
    // information. 
    var person = ctx.Persons.Single(x => x.PersonID == 12); 

    // Many lines of code... 
    // Many lines of code... 
    // Many lines of code... 

    // Okay, if we have reached this point in the code, the person wants to 
    // send all his friends a postcard, so we need the person's friends and 
    // their addresses. 

    // I want to eagerly load the person's friends' addresses, but the Include 
    // method is not allowed. The property "Friends" is just an ObservableCollection. 
    var friends = person.Friends.Include("Address").ToList(); 

    // So, I must do the following: 
    var friends = person.Friends.ToList(); 

    // Now I will output the address of each friend. This is where I have the 
    // SELECT N+1 problem. 
    foreach(var friend in friends) 
    { 
     // Every time this line is executed a query (SELECT statement) is sent 
     // to the database. 
     Console.WriteLine(friend.Address.Street); 

    } 

} 

任何想法,我應該做什麼?

回答

1

這對明確裝載的良好局面 - 第三個選項加載相關實體與實體框架之外急切和懶惰加載:

using (var ctx = new DbContext()) 
{ 
    var person = ctx.Persons.Single(x => x.PersonID == 12); 

    // ... 

    // the following issues one single DB query 
    person.Friends = ctx.Entry(person).Collection(p => p.Friends).Query() 
     .Include(f => f.Address) // = .Include("Address") 
     .ToList(); 

    foreach(var friend in person.Friends) 
    { 
     // No DB query because all friends including addresses 
     // have already been loaded 
     Console.WriteLine(friend.Address.Street); 
    } 
} 

這裏的關鍵是.Query()它返回一個可查詢的Friends集合並允許您爲朋友收藏添加任意附加查詢邏輯 - 例如篩選,訂購,加入其他相關數據(= Include),聚合(例如Count朋友)等。

+0

謝謝一百萬......這正是我所需要的。 – HydroPowerDeveloper 2013-05-11 02:50:01

+0

@Slauma ...我終於搞定了......我需要添加「使用System.Data.Entity;」使其工作。再次感謝您的幫助......我真的很感激! =) – HydroPowerDeveloper 2013-05-11 03:16:51