【问题标题】:Unexpected - Cannot compare elements of type 'System.Int32[]'. Only primitive types, enumeration types and entity types are supported意外 - 无法比较“System.Int32[]”类型的元素。仅支持原始类型、枚举类型和实体类型
【发布时间】:2015-09-11 03:50:19
【问题描述】:

任何想法在 EF DbContext 查询中可能存在什么问题?据我了解,这应该根据fellow SO poster 工作。

我尝试过 Lists,null,not null 检查,但无济于事。但是,如果我删除空检查并留下Contains(),则该查询确实有效。但是,如果 testIDs 为空,则要求返回所有记录。

var testIDs = new int[] { 1, 3 };
var test = session.All<VendorBooking>(x => testIDs == null || testIDs.Contains(x.VendorServiceID)).ToList();

(session.All 只使用context.Set&lt;T&gt;.Where())

抛出异常:'System.NotSupportedException' in EntityFramework.SqlServer.dll

附加信息:无法比较类型的元素 'System.Int32[]'。只有原始类型、枚举类型和实体 支持类型。

非常感谢

【问题讨论】:

  • 您使用什么版本的 EF 和 .net?
  • EntityFramework v6.1.3(最新的 AFAIK),.NET 4.5.1

标签: c# .net entity-framework lambda


【解决方案1】:

可能是这样的。此外,您可以提取常用部分并使其更短。

var testIDs = new int[] { 1, 3 };
if (testIDs == null)
{
    var test = session.All<VendorBooking>()
        .ToList();
}
else
{
    var test = session.All<VendorBooking>(x => testIDs.Contains(x.VendorServiceID))
       .ToList();
}

【讨论】:

  • 我明白了。或者只是通过 if/else 附加到 Where() 子句。好主意。谢谢。我对 EF 感到非常惊讶,我认为应该从根本上支持数组的 null 检查。
  • @GONeale somethimes EF 很奇怪,是的
  • @GONeale 我想,我有一个想法,为什么会这样。在 c# (.net) 中,我们有集合(数组、列表等),但在 sql-server 中没有集合。因此,linq2sql 无法将集合传递给服务器以检查它是否为空
  • 我认为在 EF 中准备查询时,它会简单地识别数组 'testIDs == null' 并知道在 T-SQL 中将其写为 1 = 1 OR IN (1,2) 等。如果我认为 EF 团队采用了这个功能,那是可以做到的。
  • 不必那样做,你可以按照我在我的回答中发布的那样做:!testIDs .Any() ...
【解决方案2】:

testIds 不能为空,所以试试这个

var testIDs = new int[] { 1, 3 };
var test = session
   .All<VendorBooking>(x => testIDs.Contains(x.VendorServiceID))
   .ToList();

修订

var results = (testIds == null || testIds.Length == 0)
  ? session.All<VendorBooking>()
  : session.All<VendorBooking>(x => testIDs.Contains(x.VendorServiceID));
var test = results.ToList();

【讨论】:

  • 如果排除此检查,如何返回 testID 为空的所有记录?
  • 看来@Backs 有你的答案。
  • 谢谢理查德。
【解决方案3】:
    var test = session.All<VendorBooking>(x => testIDs.Contains()==0 || 
    testIDs.Contains(x.VendorServiceID)).ToList();

这正常工作。不要被 OR 运算符弄糊涂了,所以只有一个条件必须是 true 才能使完整表达式为 true。当任何值传递给testIDs 时,testIDs.Contains(x.VendorServiceID) 的计算结果为 true,否则当传递 null 时,testIDs.Contains()==0 为真。

【讨论】:

    【解决方案4】:

    你可以试试这个:

    var testIDs = new int[] { 1, 3 };
    var test = session.All<VendorBooking>(x => !testIDs.Any() || 
    testIDs.Contains(x.VendorServiceID)).ToList();
    

    【讨论】:

    • 这会导致testIds 成为 SQL 查询的一部分,这根本没有必要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 2014-11-16
    • 2019-05-09
    • 1970-01-01
    相关资源
    最近更新 更多