Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 需要一些指导,了解EF Core在内部如何处理此查询_C#_Entity Framework Core - Fatal编程技术网

C# 需要一些指导,了解EF Core在内部如何处理此查询

C# 需要一些指导,了解EF Core在内部如何处理此查询,c#,entity-framework-core,C#,Entity Framework 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 s

我正在代码中构建此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+,它会引发以下异常:

我认为问题在于查询的组部分。它之所以存在,是因为它派生了TemplateCount,但我找不到一种重写它的方法

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

试试这个:

var query=来自context.Tasks.AsNoTracking中的t 将t.ID上的context.WorkTemplates中的wt等于wt.TaskID连接到tmp中 从tmp.DefaultIfEmpty中的tt 根据新的{t.ID,t.Name,t.Instructions,t.ManualOnly,t.Timestamp}将tt分组到grp中 选择新的 { grp.Key.ID, grp.Key.Name, grp.Key.Instructions, 仅适用于grp.Key.MANUAL, grp.Key.Timestamp, TemplateCount=grp.Sumx=>x.ID>0?1:0 } .Selectx=>新任务{ID=x.ID,Name=x.Name,Instructions=x.Instructions,ManualOnly=x.ManualOnly,Timestamp=x.Timestamp,TemplateCount=x.TemplateCount};
只需简化tmp.DefaultIfEmptynew工作模板,更正分组并用Sum替换Count

ORM的任务是从实体之间的关系生成联接。如果您必须编写显式联接,则模型有问题。请阅读异常消息。如果实体具有正确的关系,并且您希望找到每个任务的模板数,则可以选择所有任务,并为每个任务选择templates.Count,例如context.Tasks.Selecttask=>new{task=task,Count=t.templates.Count}首先需要解决的问题是模型。在这之后,错误就清楚了——查询正在尝试一些无法转换为SQL的东西。按整个对象分组肯定很奇怪,尤其是当您根本不想按该对象分组时。LINQ不是SQL或SQL的替代品。如果您试图将SQL查询转换为SQL,那么在某个时候会遇到麻烦。这一点现在是正确的。如果不想解决实际问题,可以尝试对任务和计数运行单独的查询。您不需要对任务进行分组,因此可以使用单个查询加载任务。完成此操作后,可以提取其ID并查询模板,其中Template.TaskID包含在TaskID列表中。例如context.Templates.Wheret=>ids.Containst.TaskId.GroupByt=>t.TaskId.Selectg=>new{TaskID=g.Key,Count=g.Count。最初的问题当然只是带有参数EFC 5的DefaultIfEmpty重载支持条件计数。但这是一种编写EFC查询的荒谬方式,不应该被容忍。在SQL中,您可能需要做这样的事情,但在EFC中,首先要有详细信息的多个主表,然后将其重新分组st进行详细计数是荒谬的。正如人们在评论中所说,在EFC中,这应该是从集合导航属性的master+count中简单地选择。@IvanStoev,只同意count。拥有所有可能的导航不是规则。谢谢,这很好。