3

我一直在使用設計模式,使用實體框架分析器後似乎可能是相當愚蠢的。使用實體框架和查詢而不創建大量查詢(避免N + 1)

我已經擴展我的實體類,使其屬性是與該實體關聯的集合的過濾視圖。就像這樣:

public IEnumerable<Member> ActiveMembers 
{ 
    get 
    { 
     return Members.Where(t => t.LeftDate == null); 
    } 
} 

正如我主要興趣在誰沒有離開俱樂部這個屬性是非常有用的,似乎是有道理的成員。

但是運行EF Profiler後,我現在知道這經常導致N + 1問題。如果我循環遍歷成員並且還想顯示他們的地址,那麼每個地址請求都會導致額外的數據庫查詢。

我從這個question I asked,我可以改變我的財產要知道:

return Members.CreateSourceQuery().Include("Address") 
       .Where(t => t.LeftClubDate == null); 

這將擺脫在這種情況下,N + 1的問題,但我並不總是希望地址信息和我可能要遵循會員的另一個導航屬性。

理想情況下,我希望能夠像ActiveMembers一樣保持過濾屬性的靈活性,並且能夠隨後決定要在查詢中包含哪些屬性。像這樣:

var membersToDisplay = ActiveMembers.Include("Address").ToList(); 

這是可能的,還是我需要處理我的過濾的屬性的想法?

回答

3

不,不可能在IEnumerable上致電IncludeIncludeObjectQuery/DbQuery的功能。有可能在IQueryable(使用EFv4.1或自定義擴展名)上調用Include,但它仍然在內部投遞查詢到ObjectQueryDbQuery,並且拋出異常,如果無法執行轉換。你必須重新設計你的應用程序。

我並不總是需要的地址 信息,我可能要遵循 從 會員另一個導航屬性。

您必須根據您的當前需求填寫數據或與N + 1問題一起生活。例如,您可以使用單獨的linq查詢:

var clubId = ActiveClub.Id; 
var members = (from member in context.Members.Include("Address") 
       where member.LeftDate == null and member.ClubId == clubId 
       select member).ToList(); 
+0

感謝您的幫助。看起來我需要重新設計一些東西。 – 2011-05-14 17:17:06