首页 > 解决方案 > 需要一些指导来了解 EF Core 在内部对此查询的作用

问题描述

我正在代码中构建这个 IQueryable:

var query = (from t in context.Tasks.AsNoTracking()
         join wt in context.WorkTemplates on t.ID equals wt.TaskID into tmp
         from tt in tmp.DefaultIfEmpty(new WorkTemplate())
         group tt by t into grp
         select new
         {
             grp.Key.ID,
             grp.Key.Name,
             grp.Key.Instructions,
             grp.Key.ManualOnly,
             grp.Key.Timestamp,
             TemplateCount = grp.Where(x => x.ID > 0).Count()
         })
         .Select(x => new Task { ID = x.ID, Name = x.Name, Instructions = x.Instructions, ManualOnly = x.ManualOnly, Timestamp = x.Timestamp, TemplateCount = x.TemplateCount })
         .AsQueryable();

我的要求是它必须是一个 IQueryable 语句,因为它被移交给一个网格控件,该控件使用它以持续的方式获取数据。

EF Core 2.2.6 没有抱怨这个查询,但显然那是因为它正在做它必须做的事情,以便至少在本地执行它的一部分。现在我已经迁移到 EF Core 5+,它会抛出这个异常:

在此处输入图像描述

我认为问题是group查询的一部分。它在那里是因为它派生了TemplateCount,但我找不到重写它的方法。

由于此查询永远不会提取足够的数据来导致性能问题,因此本地执行很好。更重要的是它可以作为单个 IQueryable 工作。

标签: c#entity-framework-core

解决方案


试试这个:

var query = (from t in context.Tasks.AsNoTracking()
         join wt in context.WorkTemplates on t.ID equals wt.TaskID into tmp
         from tt in tmp.DefaultIfEmpty()
         group tt by new { t.ID, t.Name, t.Instructions, t.ManualOnly, t.Timestamp } into grp
         select new
         {
             grp.Key.ID,
             grp.Key.Name,
             grp.Key.Instructions,
             grp.Key.ManualOnly,
             grp.Key.Timestamp,
             TemplateCount = grp.Sum(x => x.ID > 0 ? 1 : 0)
         })
         .Select(x => new Task { ID = x.ID, Name = x.Name, Instructions = x.Instructions, ManualOnly = x.ManualOnly, Timestamp = x.Timestamp, TemplateCount = x.TemplateCount });

只需简化tmp.DefaultIfEmpty(new WorkTemplate())、更正分组并替换CountSum


推荐阅读