比较一个可为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解决方法?

比较一个可为null的列会引发"空";无法强制转换类型";例外

怎么样

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 );