为什么 LINQ 生成的 SQL 包含同一列的多个 "IS NULL" 条件

Why does LINQ generated SQL include multiple "IS NULL" conditions for the same column

针对 SQL Server 2012 数据库的以下查询,使用 Entity Framework Core 3.1:

        var tows = await _context.DataEntryTow
            .Where(t => _context.DataEntrySample
                        .Any(s => s.TowId==t.TowId && (s.MicroscopeId != "0" || s.MicroscopeId == null)))
            .Select (t => new { text = t.TowId, value = t.TowId });

生成这个 SQL:

SELECT d.tow_id AS text
FROM data_entry_tow AS d
WHERE EXISTS (
    SELECT 1
    FROM data_entry_sample AS d0
    WHERE (d0.tow_id = d.tow_id) AND (((d0.microscope_id <> '0') OR (d0.microscope_id IS NULL)) OR (d0.microscope_id IS NULL)))

我不认为我做错了什么,我相当确定查询优化器会消除第二个(d0.microscope_id IS NULL),但它似乎仍然就像 LINQ 代码中的错误。

MicroscopeId定义为:

    public string MicroscopeId { get; set; }

字段 MicroscopeId 声明为可为空。因此,为了在 null != "0"true 但在 SQL 中 null <> '0' 为 false 时模仿 LINQ to Objects 行为,EF Core 会生成额外的 OR 条件。

要禁用这一代,您必须在构建 DbContextOptions 时指定:

optionsBuilder.UseSqlServer(constr, b => b.UseRelationalNulls(true) );

附加信息:https://docs.microsoft.com/en-us/ef/core/querying/null-comparisons#using-relational-null-semantics