比较可空列会抛出“无法转换类型...”异常

时间:2013-03-14 02:05:03

标签: 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(n => n.LibraryID.Equals(lid));

给出例外:

  

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

然后我尝试了:

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

得到了:

  

无法将类型'System.Nullable`1'强制转换为'System.Object'。 LINQ to Entities仅支持转换EDM原语或枚举类型。

和此:

var results = context.NewsItems
    .Where(n => object.Equals(lid, n.LibraryID));

给出与最后一个相同的异常。

现在我很绝望,所以我试图让事情复杂化(比如其他论坛建议,例如here):

var results = context.NewsItems
    .Where(n => (lid == null ? n.LibraryID == null : n.LibraryID == lid));

但仍然得到同样的例外。

那么......任何 SIMPLE 解决方法?

5 个答案:

答案 0 :(得分:2)

怎么样

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

答案 1 :(得分:1)

嗯,第一个片段应该有用。我曾经多次使用这样的无用之物。我要做的第一件事就是进行健全性检查,以确保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);

答案 2 :(得分:0)

根据MSDN文档(我最终发现),。Where()只会过滤您的收藏。如果你想查看是否有实际结果,可以通过延迟执行带有.ToList(),GetEnumerator的过滤查询或使用foreach枚举集合来解决;

  

此方法通过使用延迟执行来实现。眼前的   返回值是存储所有信息的对象   需要执行操作。此方法表示的查询   在通过调用对象枚举对象之前不会执行   直接使用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();

答案 3 :(得分:0)

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

答案 4 :(得分:0)

似乎EF找不到正确的运算符重载。因此,如果设置lid = null,则会产生错误的结果。

通过在查询中添加AsEnumerable()来将linq用于对象,一切正常:

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