EF为可为空的实体生成了不需要的SQL

问题描述

我有一个实体,该实体使用另一个可以为null的实体

class Parent 
{
   int? ChildId;
   Child Child;
}
class Child
{
   decimal Property;
}

我正在尝试对child属性进行过滤,但它会生成一个奇怪的sql

Parents.Select(p => new { X = p.Child.Property <> 0 ? 1 : 0  })

但是当我查看sql时,它生成了:

(([p.Child].[Property] <> 0.0) OR [p.Child].[Property] IS NULL).

我想要的sql

(([p.Child].[Property] <> 0.0) OR [p.Child].[Property] IS NOT NULL)

可以不使用p.Child != null && p.Child.Property <> 0来实现。我试过了,但它仍然添加了IS NULL条件。

解决方法

这似乎是由于EF Core 2中的错误/缺陷引起的,而该错误/缺陷已在EF Core 3中修复,因为在那里没有发生。

我已经尝试了所有可能的语法技巧,并且不管OR IS NULL选项如何,它都会继续插入该UseRelationalNulls条件。

最后我就能得到想要的

[p].[ChildId1] IS NOT NULL AND ([p.Child].[Property] <> 0.0

使用超反直觉表达进行翻译

p.Child != null && !(p.Child.Property == 0)

(正如您提到的,自然的书写方式

p.Child != null && p.Child.Property != 0

仍然包括OR IS NULL条件,尽管它不影响结果)