2011-03-17 54 views
12

我遇到GROUP BY和急切加載的問題。我試圖解釋我在做什麼。 我查詢事件Linq/EF,急切加載和GROUP BY問題

一個DataContext CTX事件類具有以下屬性

string Description 
DateTime Date 
bool IsDeleted 
Guid SubjectId 
string Title 
DateTime Created 
Guid ForProjectId 

Person TriggeredBy 
List<Guid> Targets 

有muttiple事件具有相同SubjectId,我想最終擁有獨特SubjectIds和事件是該組中最新的。我結束了以下查詢。

var events = from x in 
      (from e in ctx.Events 
       .Include("TriggeredBy") 
       .Include("Targets") 
       group e by e.SubjectId 
       into g 
       select new 
        { 
         GroupId = g.Key, 
         EventsWithSameSubjectId = g, 
        } 
      ) 
       select x.EventsWithSameSubjectId 
       .OrderByDescending(y => y.Created).FirstOrDefault(); 

查詢編譯正常並返回正確的結果集。但是包含的屬性始終爲空。

當我剝查詢,看是否eagor負載正常工作....

var events = (from e in ctx.Events.OfType<DataNotificationEvent>() 
       .Include("TriggeredBy") 
       .Include("Targets") 
       select e).ToList(); 

這回與所有包含的屬性的事件。

這是一個已知的問題/錯誤與Linq/EF或有什麼辦法我可以擺脫這個錯誤。

問候

文森特OTTENS

+0

當您將其與分組(和子選擇和投影)結合使用時,存在熱切加載的問題。看看這個問題:http://stackoverflow.com/questions/4474951/entity-framework-include-is-not-working/4475504#4475504答案中的兩個鏈接文章可能會幫助您找到解決方法。 – Slauma 2011-03-17 20:02:00

回答

9

你投射到一個匿名類型,所以Include()是不會這樣的工作。因爲你使用group所做的並投影到匿名類型中的方法是更改​​查詢的形狀。這拋出了急切的加載。閱讀this article可能會有所幫助。

2

thnx快速回答。你指出我正確的方向。這是我想出的解決方案:

using MyFunc = Func<ExtendedCoreContext, Guid, IQueryable<DataNotificationEvent>>; 

private static readonly MyFunc GetMentionsNewCompiledQuery = 

    CompiledQuery.Compile<ExtendedCoreContext, Guid, IQueryable<DataNotificationEvent>>(

     (ctx, personId) => ((ObjectQuery<DataNotificationEvent>)(
      from x in (
       from e in ctx.Events.OfType<DataNotificationEvent>() 
       group e by e.SubjectId 
       into g 
       select g.OrderByDescending(p => p.Created).FirstOrDefault() 
      ) 
      orderby x.Created descending 
      where x.Targets.Any(t => t.Id == personId) 
      select x 
     )) 
      .Include(EntityProperties.Event.TriggeredBy) 
      .Include(EntityProperties.DataNotificationEvent.Targets) 

    );