2011-10-08 74 views
1

我有實體「想法」,它具有子實體集合「ChildIdeas」。我需要加載「ChildIdeas」的想法清單和數量(只計數!)。 我可以這樣做:實體框架,性能調優

預先加載

from i in _dataContext.Ideas.Include("ChildIdeas") ... 

優點:所有必要的數據通過一個請求得到;缺點:加載不必要的數據。我需要ChildIdeas只計數,不完整ChildIdeas名單

明確裝載

from i in _dataContext.Ideas ... 

idea.ChildIdeas.Loading() 

優點:無; 缺點:許多請求(ideas.count + 1),而不是一個,負載不需要的數據

獨立請求

from i in _dataContext.Ideas ... 

_repository.GetCountChildIdeas(idea.ID); 

優點:只加載必要的數據; 缺點:許多請求(ideas.count + 1)而不是一個

所有3種類型都有缺點。也許存在任何方式來只加載必要的數據?如果是 - 它是什麼,如果不是 - 哪種方式最適合這種情況?

[ADDED] 後負載測試(1個用戶)我有網頁加載(在秒): 渴望兒童思想 - 1.31秒 明確的兒童觀 - 1.19秒 外部請求 - 1.14秒

所以,對我而言,熱切的方式是最糟糕的......爲什麼明確的方式更好?

回答

2

您應該使用投影。 Count子想法不是堅持Idea實體的一部分,因此創建包含Idea實體和Count屬性的所有屬性的新非映射類型。

public class IdeaProjection 
{ 
    public int Id { get; set; } 
    // Other properties 
    public int Count { get; set; } 
} 

現在你可以使用簡單的投影查詢來獲取與單個請求一切不加載任何額外的數據:

var query = from x in context.Ideas 
      where ... 
      select new IdeaProjection 
       { 
        Id = x.Id, 
        // Mapped other properties 
        Count = x.ChildIdeas.Count() 
       }; 

缺點是IdeaProjection不是實體,如果你想使用它的更新那麼你必須將它轉換回Idea並告訴EF有關變化。從性能角度來看,您最好從EF中獲得而無需恢復到SQL或存儲過程。

+0

我添加您的示例關於急切加載數據重複(http://stackoverflow.com/questions/5521749/how-many-include-i-can-use-on-objectset-in-entityframework-to-retain-performance/5522195#5522195)作爲可能的解釋,爲什麼OP已經測試了比渴望加載更慢的性能。 – Slauma

+0

據我所知,我們可以將Ideas類擴展到一個屬性... –

+0

不,你不能因爲投影不可能映射類。 –