为啥 EF Core 会生成倒位比较

Posted

技术标签:

【中文标题】为啥 EF Core 会生成倒位比较【英文标题】:Why EF Core generates inverted bit comparison为什么 EF Core 会生成倒位比较 【发布时间】:2021-06-15 16:47:31 【问题描述】:

我们正在尝试将我们的项目升级到 .net core 5。现在我们正在努力解决一个奇怪的 EF 行为。 一个简单的查询:

context.Set<Order>().Where(o => o.Archived == false)

其中 Order.Archived 在数据库中位 NOT NULL,生成这样的查询:

select * from Order where Archived <> CAST(1 as bit)

为什么会这样?我们希望有如下查询:

select * from Order where Archived = CAST(0 as bit)

这种反转可能会阻止数据库在更复杂的查询中使用正确的索引。 有没有办法让 EF 生成更直接的查询?

P.S.:我们也尝试了同样的方法来处理可空字段。我们确实收到了预期的查询。

【问题讨论】:

“这种倒置可能会阻止在更复杂的查询中使用正确的索引”——那么这个特定的翻译现在真的有问题吗? 所以,在 github 中创建问题。 o =&gt; !o.Archived 产生了什么?如果这不起作用,因为 Archived 可以为空(即使它在数据库中不可为空),您的模型可能需要调整。 @JeroenMostert Archived 在模型和数据库中也不能为空。 o => !o.Archived 产生同样奇怪的查询。 @AakashM 是的,这有问题。 【参考方案1】:

我对此进行了研究,对于可为空的属性,它运行良好,正如预期的那样。 对于不可为空的属性,我发现了这个技巧,它给出了预期的结果

context.Set<Order>().Where(o => new []false.Contains(o.Archived))

在这种情况下,我们会收到以下 sql 查询:

select * from Order where Archived = CAST(0 as bit)

【讨论】:

以上是关于为啥 EF Core 会生成倒位比较的主要内容,如果未能解决你的问题,请参考以下文章

比较 EF Core Linq 查询中的 DateTime

向“datetime2”列添加值导致溢出。 EF Core 日期比较

如何比较 EF Core 插值查询中的整数列表

EntityFramework 7 更名为EntityFramework Core(预发布状态)

在.NET Core类库中使用EF Core迁移数据库到SQL Server

为啥我的 ASP.NET Core 3.1 控制器会自动为从视图返回的 EF Core 模型分配 ID?