LINQ To SQL异常:除Contains运算符外,本地序列不能用于查询运算符的LINQ to SQL实现

时间:2009-11-10 23:58:33

标签: linq linq-to-sql

考虑这个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实现

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

4 个答案:

答案 0 :(得分:33)

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

searchTerms.Contains(c.Email)

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

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

c.addressLine1.Contains(...)

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

答案 1 :(得分:11)

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

我收到了与你相同的错误消息,即使我正确地使用了Contains()方法,我花了很长时间才弄清楚我的问题的根源是将IEnumerable返回到需要的东西进一步过滤L2S查询的结果。一旦我将函数的返回类型更改为IQueryable,问题就消失了。有意义的是,看到IEnumerable无法进一步过滤,但IQueryable可以。

答案 2 :(得分:0)

我收到同样的错误,但上面发布的解决方案都没有为我工作。

对我有用的是将db.Custs投射到第一列表中,如下所示:

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

我不知道为什么会有效,但确实如此。

答案 3 :(得分:0)

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