【问题标题】:Linq/EF, Eager loading and GROUP BY issuesLinq/EF、Eager loading 和 GROUP BY 问题
【发布时间】:2011-03-17 18:28:22
【问题描述】:

我遇到了 GROUP BY 和急切加载的问题。我试图解释我在做什么。 我正在为事件查询数据上下文 ctx

事件类具有以下属性

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

Person TriggeredBy
List<Guid> Targets 

有多个具有相同 SubjectId 的事件,我希望最终拥有具有唯一 SubjectId 并且是该组中最新的事件。我最终得到以下查询。

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 的一个已知问题/错误,还是有什么办法可以摆脱这个错误。

问候

文森特·奥滕斯

【问题讨论】:

  • 当您将预加载与分组(以及子选择和投影)结合使用时,会出现预加载问题。看看这个问题:stackoverflow.com/questions/4474951/…答案中的两篇链接文章可能会帮助您找到解决方法。

标签: linq entity-framework


【解决方案1】:

您正在投影到匿名类型,所以Include() 不会那样工作。因为您对 group 所做的并投影到匿名类型是为了更改查询的形状。这抛弃了急切的加载。阅读this article 可能会有所帮助。

【讨论】:

    【解决方案2】:

    感谢您的快速回答。你为我指明了正确的方向。这是我想出的解决方案:

    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)
    
        );
    

    【讨论】:

      猜你喜欢
      • 2011-09-29
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-05
      • 1970-01-01
      • 2019-04-27
      相关资源
      最近更新 更多