C# LINQ查询List字段非空时遇Nullable object must have a value报错
Nullable object must have a value错误 我来帮你拆解这个问题,以及对应的靠谱解决办法:
问题根源
你碰到的这个System.InvalidOperationException,本质是Entity Framework在把你的LINQ表达式转换成SQL查询时,没办法正确处理集合导航属性WorkItemItemFailReasons != null的判断逻辑。
这里要敲个重点:EF里集合类型的导航属性(比如你的List<xWorkItemItemFailReason>),正常加载时通常会被初始化为空集合而非null——除非你手动给它设过null,或者没正确加载关联数据触发了延迟加载异常。直接写!= null会让EF尝试解析底层的关联外键(大概率是可空值类型),当外键为null时就会抛出这个“可空对象必须有值”的报错。
正确的处理方案
1. 判断集合是否有元素(最常用最靠谱)
如果你实际需求是筛选出存在失败原因记录的WorkItem,直接用Any()方法就行,EF会自动转换成SQL的EXISTS查询,高效又不会踩坑:
_db.tblWorkItem.Where(x => x.WorkItemItemFailReasons.Any())
2. 显式加载导航属性后判断非空(特殊场景)
如果你确实需要判断集合本身是否不为null(这种场景极少,毕竟EF默认会初始化空集合),得先通过Include()显式加载关联数据,再用C# 9+的is not null语法判断,EF能更好地解析这个表达式:
_db.tblWorkItem.Include(x => x.WorkItemItemFailReasons) .Where(x => x.WorkItemItemFailReasons is not null)
3. 直接检查对应的外键属性(如果有定义)
如果你的tblWorkItem模型里有和WorkItemItemFailReasons对应的外键字段(比如WorkItemFailReasonId),可以直接判断外键是否不为null,绕开导航属性的转换问题:
_db.tblWorkItem.Where(x => x.WorkItemFailReasonId != null)
总结
优先选第一种方案,因为它最贴合你筛选“有失败原因”记录的实际需求,同时完美避开EF表达式转换的坑。只有特殊场景下需要判断集合本身是否非空时,再考虑后面两种方法。
内容的提问来源于stack exchange,提问作者Dmitry Vasilyuk Just3F

