我有以下简单的查询:

var students = from s in dbContext.Students
               select new 
                      {
                          Name = s.Name,
                          HasGrades = s.Grades.Where(x => x.IsActive).Count() == 1
                      };

HasGrades是布尔值,只有当学生正好存在一个活动分数时,才必须显示为true.

我有点困惑为什么EF Core将其翻译成两个子查询,并额外判断COUNT(*)个结果与null?Postgr COUNT(*)永远不会返回null:

SELECT 
    s."NAME" AS "Name", 
    ((SELECT COUNT(*)::INT
      FROM "GRADES" AS p0
      WHERE (s."NAME" = p0."NAME") AND p0."IS_ACTIVE") = 1) 
        AND (((SELECT COUNT(*)::INT
               FROM "GRADES" AS p0
               WHERE (s."NAME" = p0."NAME") AND p0."IS_ACTIVE") IS NOT NULL)) AS "HasGrades"
FROM 
    "STUDENTS" AS s

最新情况:

如果我改变这条线

HasGrades = s.Grades.Where(x => x.IsActive).Count() == 1

对此:

HasGrades = s.Grades.Where(x => x.IsActive).Count() == 1 ? true : false

那么它就被翻译成

 CASE
    WHEN (
        SELECT COUNT(*)::INT
        FROM "GRADES" AS p1
        WHERE (p."NAME" = p1."NAME") AND p1."IS_ACTIVE") = 1 THEN TRUE
    ELSE FALSE
END

看起来这是一个更好的结果

推荐答案

EF Core本身并没有生成这个SQL——它是EF Core配置为使用的查询提供程序(我猜是Npgsql.EntityFrameworkCore.PostgreSQL个).

编写LINQ查询提供程序很难.开发人员通常会按照以下顺序设置优先级:

  • 使生成的SQL正确
  • 快速生成SQL
  • 使生成的SQL可读

由于复杂的代码会导致更多的错误,他们通常会做出让their个代码更简单的 Select ,即使这会使生成的SQL变得更复杂.我猜这就是其中一个案子.

COUNT(*)不会返回NULL,而是返回all the other aggregate functions will.查询提供程序的开发人员很可能认为,他们可以通过相似地对待所有聚合函数来保持代码更简单、更少出错.PostgreSQL的查询引擎可能会识别到DDL(*)不能生成null,并生成相同的查询计划.

Csharp相关问答推荐

当Visual Studio处于升级管理模式时,无法安装Torch运行时

如何禁用ASP.NET MVP按钮,以便无法使用开发人员控制台重新启用它

在Dapper中使用IasyncEum重写GetAsyncEum方法

使用yaml将Azure函数代码部署到FunctionApp插槽时出现问题(zip未找到)

Monty Hall游戏节目模拟给我50/50的结果

C#中使用BouncyCastle计算CMac

在C#中使用类中的对象值

JSON空引用异常仅在调试器中忽略try-Catch块,但在其他上下文中捕获得很好

TCPClient阅读流

如何注册类使用多级继承与接口

单行上的ReSharper数据标注

为什么无法将对象转换为泛型类型

HttpRequestMessage.SetPolicyExecutionContext不会将上下文传递给策略

异步任务调用程序集

WinUI 3中DoubleCollection崩溃应用程序类型的依赖属性

用C#从XML内部元素中获取特定值

try 创建一个C#程序,该程序使用自动实现的属性、覆盖ToString()并使用子类

如何在使用Google.Drive.apis.V3下载文件/文件夹之前压缩?

与另一个对象位于同一位置的对象具有不同的变换位置

如何获取我在SQL中输入的值