EF Core 5中jsonb字段null检查被翻译为FALSE常量问题咨询
问题原因
- EF Core 处理映射为 JSON 字段的嵌套属性时,默认会优化掉它认为「永远不成立」的判断:当你通过 Fluent 接口把
MyJsonField配置为 jsonb 类型的整体映射后,EF 默认假设 JSON 结构和 C# 类型完全匹配,嵌套的Array属性不会出现 JSON 侧为 null 的情况,因此会把myTypes.JsonField.Array == null直接判定为恒假,翻译为FALSE。 - 你写的
OR逻辑里的 null 检查被删除,也是因为 EF 表达式优化阶段认为前半段条件恒假,直接简化为仅保留后半段的JsonContains逻辑。
正确校验方案
直接通过 EF 提供的 JSON 函数显式判断 JSON 节点的 null 状态,不要直接判断 C# 侧的嵌套属性 null,示例代码如下:
// 同时兼容 整个JsonField为null、Json内部Array节点为null、Array包含指定值三种场景 query = query.Where(myTypes => // 整个JsonField字段为null myTypes.JsonField == null // JsonField存在,但内部Array节点为null || EF.Functions.JsonIsNull(myTypes.JsonField, "Array") // Array不为null且包含目标值 || EF.Functions.JsonContains(myTypes.JsonField.Array, "5"));
上述代码会被正确翻译为包含 null 判断的 SQL,生成的SQL结构大致如下:
SELECT ... FROM myTypes AS m WHERE m.JsonField IS NULL OR m.JsonField->'Array' IS NULL OR m.JsonField->'Array' @> 5
如果你希望直接判断myTypes.JsonField.Array == null就能正确翻译,可以在 Fluent 配置中对JsonField下的Array属性显式配置允许 null,关闭 EF 的默认优化:
modelBuilder.Entity<MyType>() .OwnsOne(t => t.JsonField, b => { b.Property(j => j.Array).IsRequired(false); }) .ToJson(); // 对应你原来的jsonb配置
内容的提问来源于stack exchange,提问作者VoidName
相关产品推荐
相关产品推荐

