Linq / EF,Eager loading和GROUP BY问题

时间:2011-03-17 18:28:22

标签: linq entity-framework

我遇到了GROUP BY和急切加载的问题。我试着解释一下我在做什么。 我正在查询datacontext ctx的事件

事件类具有以下属性

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

Person TriggeredBy
List<Guid> Targets 

有多个具有相同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();

查询编译正常并返回正确的结果集。但包含的属性始终为null。

当我剥离查询以查看eagor加载是否正常工作....

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

这将返回包含所有包含属性的事件。

这是Linq / EF的已知问题/错误还是有任何办法可以摆脱这个错误。

此致

Vincent Ottens

2 个答案:

答案 0 :(得分:9)

您正在投射到匿名类型,因此Include()不会像那样工作。因为您对group所做的并投射到匿名类型是改变查询的形状。抛出急切的装载。阅读this article可能有所帮助。

答案 1 :(得分: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)

    );