【问题标题】:LINQ To SQL exception: Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains operatorLINQ To SQL 异常:不能在查询运算符的 LINQ to SQL 实现中使用本地序列,但 Contains 运算符除外
【发布时间】:2009-11-10 23:58:33
【问题描述】:

考虑这个 LINQ To SQL 查询。其目的是获取搜索词的字符串 [] 并将这些词应用于 SQL 表上的一堆不同字段:

string[] searchTerms = new string[] {"hello","world","foo"};
List<Cust> = db.Custs.Where(c => 
   searchTerms.Any(st => st.Equals(c.Email))
|| searchTerms.Any(st => st.Equals(c.FirstName))
|| searchTerms.Any(st => st.Equals(c.LastName))
|| searchTerms.Any(st => st.Equals(c.City))
|| searchTerms.Any(st => st.Equals(c.Postal))
|| searchTerms.Any(st => st.Equals(c.Phone))
|| searchTerms.Any(st => c.AddressLine1.Contains(st))
)
.ToList();

引发异常:

除了 Contains() 运算符外,查询运算符的 LINQ to SQL 实现中不能使用本地序列

问题: 为什么会引发此异常,如何重写查询以避免此异常?

【问题讨论】:

    标签: linq linq-to-sql


    【解决方案1】:

    在查询中将 Any 的用法替换为 Contains。例如:

    searchTerms.Contains(c.Email)
    

    这应该会得到您正在寻找的结果。它向后看,但它是正确的 - 它会为包含 searchTerms 中的所有元素的包含内的每个字段生成一个 IN 运算符。

    AddressLine1 部分​​不会以这种方式工作 - 您必须自己循环生成比较

    c.addressLine1.Contains(...)
    

    PredicateBuilder 之类的内容可能对此有所帮助。

    【讨论】:

    • @nitzmahone:谢谢,会检查 PredicateBuilder,它看起来很有希望!
    • 我担心PredicateBuilder 的出色性能会让 LinqToSql 实现令人失望,因为 LinqToSql 提供程序可能无法实现某些条件(您在问题中描述的确切问题)。
    • +1 表示.Contains() - 通常可以很好地替代 LinqToSql 不支持的方程。建议谨慎使用PredicateBuilder,即使是一个选项。
    • 我一直使用 PredicateBuilder,几乎只使用 Linq to SQL。当列列表是可变的(即“高级搜索”)时,可以节省大量时间,并且几乎是唯一的方法来进行这样的 OR'd 动态搜索。
    【解决方案2】:

    只是一个想法(与问题没有直接关系,但它可能会帮助其他观众):

    即使我正确使用了 Contains() 方法,我也收到了与您相同的错误消息,而且我花了很长时间才弄清楚我的问题的根源是将 IEnumerable 返回给需要的东西进一步过滤 L2S 查询的结果。一旦我将函数的返回类型更改为 IQueryable,问题就消失了。这是有道理的,因为 IEnumerable 不能被进一步过滤,但 IQueryable 可以。

    【讨论】:

      【解决方案3】:

      我遇到了同样的错误,但上面发布的解决方案都不适合我。

      对我有用的是将db.Custs 转换为列表first,如下所示:

      List<Cust> =db.Custs.ToList<Cust>.Where(...
      

      我不知道它为什么起作用,但它确实起作用了。

      【讨论】:

      • 它适用于您的情况,因为您绕过了数据库并正在处理集合,而不是将 Contains() 扩展方法转换为 SQL。
      【解决方案4】:

      本质上,错误是说您正在两个集合之间进行连接,其中一个是数据库表,另一个是数组。 LINQ 不是为处理这个问题而设计的——要么两者都需要在数据库中,要么都在内存中(使用Contains 时会出现特殊情况)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-06
        • 2011-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多