c# - Ef 核心字符串不包含排除 Null
问题描述
为什么当我在 Entity Framework Core 中查询字符串 Not Equals 时它会返回 NULL 值(通过附加“或 ISNULL(字段)”),但是当我查询例如“不包含”或“不 StartWith”时它会不是
我知道我可以通过手动添加到查询中以包含 NULL 来获得相同的结果,我的问题是为什么 2 在涉及 NULL 时表现不同?有什么明显的原因吗?
代码示例:
C# -dbContext.Employee.Where(x => x.jobNotes != "abc").Select(x => x.firstName).ToList();
生成的 Sql -exec sp_executesql N'SELECT [x].[firstName] FROM [Employee] AS [x] WHERE (([x].[jobNotes] <> N''abc'') OR [x].[jobNotes] IS NULL)'
C# -dbContext.Employee.Where(x => !x.jobNotes.Contains("abc")).Select(x => x.firstName).ToList();
生成的 Sql -exec sp_executesql N'SELECT [x].[firstName] FROM [Employee] AS [x] WHERE (CHARINDEX(N''abc'', [x].[jobNotes]) <= 0)'
解决方案
原因不是“明显”,但可以通过某种方式解释:
具有 C# 表达式:
x.jobNotes.Contains("abc")
只有“有效”,当 的值x.JobNotes
不是时NULL
,否则你会得到一个NullReferenceException
. 为确保您不这样做,仅NOT NULL
检查值。生成的 SQL 语句
(CHARINDEX(N''abc'', [x].[jobNotes]) <= 0)
这样做是因为对于表NULL
中的任何值jobNotes
,结果CHARINDEX
将是NULL
,如以下文档中CHARINDEX
所定义:
如果expressionToFind或expressionToSearch表达式具有 NULL 值,则 CHARINDEX 返回 NULL。
在这种情况下比较NULL
值 ( NULL <= 0
) 会导致,如比较运算符UNKNOWN
的文档中所定义:
当 SET ANSI_NULLS 为 ON 时,具有一个或两个 NULL 表达式的运算符返回 UNKNOWN。当 SET ANSI_NULLS 为 OFF 时,应用相同的规则,但等于 (=) 和不等于 (<>) 运算符除外。当 SET ANSI_NULLS 为 OFF 时,这些运算符将 NULL 视为已知值,等同于任何其他 NULL,并且仅返回 TRUE 或 FALSE(从不 UNKNOWN)。
我不确定该怎么WHERE UNKNOWN
做,因为您不能直接运行此表达式,但作为示例,表达式WHERE NULL <= 0
导致WHERE FALSE
,这意味着不返回jobNotes
列设置为的行。NULL
NULL
当您从 C# 或实体框架的角度查看查询时,不返回这些值是有道理的。当您有类似的查询时
dbContext.Employee
.Where(x => !x.jobNotes.Contains("abc"))
.Select(x => x.firstName)
.ToList()
jobNotes
并且您获得了该列所在的实体NULL
,问题就出现了:
“等等,为什么是
jobNotes
NULL?它应该NullReferenceException
因为Contains()
方法调用而抛出一个。”
因此,这可能是它不返回该jobNotes
列具有值的行的原因NULL
(并且与“不同”工作x.jobNotes != "abc"
)。
推荐阅读
- c++ - 包含 libpqxx 会导致使用 CMake 在 WSL 上构建失败
- azure - Azure Active Directory 登录页面中的隐藏后退按钮
- .net - 不再能够在我的 .NET Core3 WPF 表单上打开设计器
- python - 自定义损失函数大大减慢了多 GPU 模型的训练
- javascript - 在没有服务器访问的情况下确定您可以使用哪个 url 访问网站
- filter - 如何从 Pypsark 中的 RDD 中过滤
- python - pandas groupby:我可以通过 MultiIndex 列的一级选择 agg 函数吗?
- rust - 使用 rusoto 流式上传到 s3
- python - 将 --port 参数发送到 python
- javascript - 即使我使用 javascript 传递字符串,为什么会弹出“string.matchall 不是函数”错误?