比较一个可为null的列会引发"空";无法强制转换类型";例外
本文关键字:quot 例外 类型 转换 一个 null 比较 | 更新日期: 2023-09-27 18:03:52
我的实体NewsItem
有一个可为null的外键属性:int?
类型的LibraryID
。
我的问题是,当我查询属性并将其与除null
之外的任何值进行比较时,我会得到异常。
最初我的代码是:
int? lid = ...
var results = context.NewsItems
.Where(n => n.LibraryID == lid);
但无论lid
是什么,它都没有给我任何结果。
所以,我尝试了:
var results = context.NewsItems
.Where(n => n.LibraryID.Equals(lid));
给出例外:
无法创建类型为"System"的常数值。对象"。在此上下文中仅支持基元类型或枚举类型。
然后我尝试了:
var results = context.NewsItems
.Where(n => lid.Equals(n.LibraryID));
得到:
无法强制转换类型"System"。类型"System"的"1"可为Null。对象"。LINQ to Entities仅支持强制转换EDM基元或枚举类型
这个:
var results = context.NewsItems
.Where(n => object.Equals(lid, n.LibraryID));
给出了和上一个相同的异常。
现在我绝望了,所以我试图把事情复杂化(就像其他论坛建议的那样,比如这里(:
var results = context.NewsItems
.Where(n => (lid == null ? n.LibraryID == null : n.LibraryID == lid));
但仍有同样的例外。
所以。。。是否有SIMPLE解决方法?
怎么样
var results = context.NewsItems
.Where(n => lid.HasValue ? lid.Value == n.LibraryId.Value : (!n.LibraryId.HasValue) );
嗯,第一个片段应该可以工作了。我已经用过很多次这样的null了。我要做的第一件事是进行健全性检查,以确保LibraryID
真的是int?
,而不是long?
或类似的。
除此之外,你可以试试这个:
var results = context.NewsItems
.Where(n => (lid.HasValue ? n.LibraryID == lid.Value : !n.LibraryID.HasValue));
或者为了避免查询中的?:
:
var results = lid.HasValue
? context.NewsItems.Where(n => n.LibraryID == lid.Value)
: context.NewsItems.Where(n => !n.LibraryID.HasValue);
EF似乎没有找到正确的运算符重载。因此,如果设置lid = null
,会产生错误的结果。
通过将AsEnumerable()
添加到查询中,对对象使用linq,一切都很好:
var results = context.NewsItems.AsEnumeryble().Where(n => n.LibraryID == lid);
根据MSDN文档(我终于找到了(。Where((将只过滤您的集合。如果您想查看是否真的有结果,请通过使用延迟执行筛选后的查询来解决。ToList((、GetEnumerator或使用foreach枚举集合;
此方法是通过使用延迟执行来实现的。立即return value是一个对象,用于存储需要执行操作。此方法表示的查询直到通过调用其GetEnumerator方法,或者在Visual C#或For中使用foreach每个都在Visual Basic中。
http://msdn.microsoft.com/en-us/library/bb534803.aspx
int? lid = ...
var results = context.NewsItems
.Where(n => n.LibraryID == lid).ToList();
var results = context.NewsItems
.Where(n => n.LibraryID.HasValue && n.LibraryID.Value == lid.Value );
编辑:
之前的过滤器是基于我的理解,你想过滤到具有特定值的整数。更新后将筛选为null或值。
var results = context.NewsItems
.Where(n => !n.LibraryID.HasValue || n.LibraryID.Value == lid.Value );