C# 比较一个可为空的列会抛出;无法强制转换类型…”;例外

C# 比较一个可为空的列会抛出;无法强制转换类型…”;例外,c#,linq-to-entities,entity-framework-5,C#,Linq To Entities,Entity Framework 5,我的实体NewsItem具有可为空的外键属性:LibraryID,类型为int? 我的问题是,当我查询属性并将其与除null以外的任何值进行比较时,我会得到异常 最初我的代码是: int? lid = ... var results = context.NewsItems .Where(n => n.LibraryID == lid); 但它根本没有给我任何结果,不管lid是什么 所以,我试着: var results = context.NewsItems .Where

我的实体
NewsItem
具有可为空的外键属性:
LibraryID
,类型为
int?

我的问题是,当我查询属性并将其与除
null
以外的任何值进行比较时,我会得到异常

最初我的代码是:

int? lid = ...
var results = context.NewsItems
    .Where(n => n.LibraryID == lid);
但它根本没有给我任何结果,不管
lid
是什么

所以,我试着:

var results = context.NewsItems
    .Where(n => n.LibraryID.Equals(lid));
例外情况:

无法创建“System.Object”类型的常量值。在此上下文中仅支持基元类型或枚举类型

然后我试着:

var results = context.NewsItems
    .Where(n => lid.Equals(n.LibraryID));
得到:

无法将类型“System.null”强制转换为类型“System.Object”。LINQ to实体仅支持强制转换EDM基元或枚举类型。

这是:

var results = context.NewsItems
    .Where(n => object.Equals(lid, n.LibraryID));
给出与上一个相同的异常

现在我绝望了,所以我试着把事情复杂化(比如,像其他论坛建议的那样):

但还是有同样的例外


所以。。。任何简单的解决方法?

根据MSDN文档(我最终找到了该文档),.Where()只会过滤您的收藏。如果要查看是否确实存在结果,请通过使用.ToList()、GetEnumerator或使用foreach枚举集合来延迟执行筛选查询来解决

此方法通过使用延迟执行来实现。直接的 返回值是一个对象,它存储了所有需要的信息 执行操作所需的。此方法表示的查询 在通过调用其 GetEnumerator方法直接使用或使用Visual C#中的foreach或For 每一个都在visualbasic中


嗯,第一个片段应该有用。我已经用过很多次了。我要做的第一件事是做一个健全性检查,以确保
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);
编辑:

之前的过滤器是基于我的理解,您希望过滤到具有特定值的实体。更新后的将筛选为null或value

   var results = context.NewsItems
        .Where(n => !n.LibraryID.HasValue || n.LibraryID.Value == lid.Value );
怎么样

var results = context.NewsItems
    .Where(n => lid.HasValue ? lid.Value == n.LibraryId.Value : (!n.LibraryId.HasValue) );

EF似乎没有找到正确的操作员过载。因此,如果设置
lid=null
,则会产生错误的结果

通过向查询中添加
AsEnumerable()
来使用linq to对象,一切正常:

var results = context.NewsItems.AsEnumeryble().Where(n => n.LibraryID == lid);

什么类型的LibraryID?EF对Equals方法没有(i congress,limited)支持,但是您的第一种方法应该有效。您是否验证了正在使用的实际数据?如果您试图比较不相等的类型,编译器应该抛出异常。也就是说,检查可为null的int是否有值不是一个坏主意,尽管我会在开始查询之前检查。好的,我验证了我比较的所有类型都是
int
int?
。我尝试了这两种建议,但返回的结果不正确。无论
lid
的值是多少,都会检索
LibraryID
null
的所有记录。我的错误是,忘记在
周围加上外括号了:所以它产生了错误的查询。第一个建议有效。现在我必须在我使用的代码中更改256次。。。啊@p、 s.w.g-谢谢你@谢尼塞尔很高兴听到这个消息
   var results = context.NewsItems
        .Where(n => !n.LibraryID.HasValue || n.LibraryID.Value == lid.Value );
var results = context.NewsItems
    .Where(n => lid.HasValue ? lid.Value == n.LibraryId.Value : (!n.LibraryId.HasValue) );
var results = context.NewsItems.AsEnumeryble().Where(n => n.LibraryID == lid);