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

Aus*_*pex 1 linq sql-server linq-to-sql entity-framework-core

使用 Entity Framework Core 3.1 对 SQL Server 2012 数据库进行以下查询:

        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 });
Run Code Online (Sandbox Code Playgroud)

生成此 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)))
Run Code Online (Sandbox Code Playgroud)

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

MicroscopeId定义:

    public string MicroscopeId { get; set; }
Run Code Online (Sandbox Code Playgroud)

Svy*_*liv 5

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

要禁用此生成,您必须在构建 DbContextOptions 时指定:

optionsBuilder.UseSqlServer(constr, b => b.UseRelationalNulls(true) );
Run Code Online (Sandbox Code Playgroud)

其他信息:https://learn.microsoft.com/en-us/ef/core/querying/null-comparisons#using-relational-null-semantics