LINQ to SQL中空合并运算符未按预期工作,求原因及Bug说明
LINQ to SQL中空合并运算符在Where子句的异常问题分析
在EF Core 2.2.6中使用LINQ的Where子句处理可空decimal类型TotalBalance时,出现结果不符合预期的情况:
原代码如下:
Account.Where(n => (n.TotalBalance ?? 0) != 0) .Select(n => new { n.AccountId, n.TotalBalance })
执行后结果包含了TotalBalance为null的账户,查看生成的SQL语句,发现自动添加了额外的OR条件:
SELECT [n].[AccountID], [n].[TotalBalance] FROM [Account] AS [n] WHERE (COALESCE([n].[TotalBalance], 0.0) <> 0.0) OR [n].[TotalBalance] IS NULL
改用以下代码后结果符合预期:
Account.Where(n => n.TotalBalance != null && n.TotalBalance != 0) .Select(n => new { n.AccountId, n.TotalBalance })
问题原因与解答
这是EF Core 2.2版本的已知翻译Bug。该版本的LINQ解析器对空合并运算符??与不等于判断的组合逻辑处理错误:原本(n.TotalBalance ?? 0) !=0的语义是“将null的TotalBalance视为0,再判断是否不等于0”,即需要排除TotalBalance为null或0的记录,但解析器错误地将其翻译成了“(转0后不等于0) 或者 (原字段为null)”,导致null的记录被错误包含。
这个Bug在EF Core 3.0及后续版本中已经被修复,由于EF Core 2.2属于已弃用的旧版本,官方不再提供维护和修复,建议升级到更高版本的EF Core来避免此类问题。
内容的提问来源于stack exchange,提问作者Kluge
相关产品推荐
相关产品推荐

