2

我的 Linq 查询给出了错误:Local sequence cannot be used in LINQ to SQL implementations of query operator except the Contains operator

 var query = from product in dc.catalog
              where TextBox1.Text.Split(' ').All(s => product.Name.Contains(s))
              select product;

如何重写它来避免这个错误?

4

3 回答 3

1

相信您可以将字符串列表发送到 LINQ-to-SQL 以获取contains.

我错了。但是你能做的就是制定一个巨大的Where条款。如果要比较很多字符串,我不建议这样做,但要测试并查看。

var strings = TextBox1.Text.Split(' ').ToList();
var query = from product in dc.catalog select product;
foreach (var s in strings)
{
    query = query.Where(product => product.Name.Contains(s));
}
return query;

这将创建类似

 var query = from product in dc.catalog
             where product.Name.Contains(string1)
             where product.Name.Contains(string2)
             where product.Name.Contains(string3)
             // etc
             select product;  

这很可怕,但如果你只有几根弦,它可能会做。

更新:为了解释foreach循环是如何工作的,请考虑原始查询

 from product in dc.catalog select product

假设您的文本框包含“Hello World”。我会将它拆分为一个类似的列表{ "Hello", "World" },然后迭代该列表。

列表中的第一个是“你好”。该行query = query.Where(product => product.Name.Contains(s));导致表达式变为

from product in dc.catalog select product
.Where(product => product.Name.Contains("Hello"))

它还没有执行——它只是一个表达式树——但是Where已经被标记到原始查询上。

第二个是“世界”,并附加了表达式

from product in dc.catalog select product
.Where(product => product.Name.Contains("Hello"))
.Where(product => product.Name.Contains("World"))

这与 "Contains Hello && World" 读起来不同,但它在逻辑上是等价的 -product将测试它是否包含 "Hello",如果包含则将测试它是否包含 "World" . 它必须包含两者才能“通过”。

像这样连接表达式与连接字符串完全相同。

var letters = new List<string>(){ "H", "e", "l", "l", "o" };
string result = ""
foreach (var letter in letters)
{
    result = result + letter;
}

的值result不会是“o”。它将是“你好”。

于 2011-11-18T03:35:45.883 回答
1

正如错误所说,仅支持包含。你的列表变成了一个 SQLIN子句。
要做你想做的事,你将需要依赖 LINQ 提供的延迟执行,并构建一个 LINQ 语句来检查名称中的每个单词。

var query = dc.catalog.AsQueryable();
foreach(var s in TextBox1.Text.Split(' ') {
  string copy = s;  // Take a local copy of the string. Lambda's inside loops are fun!
  query= query.Where(product => product.Name.Contains(copy));
}

编辑:获取字符串的本地副本以希望解决 lambda 上的范围问题。周五下午 5 点在我脑海中编译,如果仍然不对,我深表歉意:)

于 2011-11-18T03:52:03.613 回答
1

我认为一种简单的方法是对对象执行查询,而不是将其传输到 SQL。

var query = from product in dc.catalog.ToList()
              where TextBox1.Text.Split(' ').All(s => product.Name.Contains(s))
              select product;

就性能而言,它不是最好的,但这取决于数据源的大小。

于 2011-11-18T11:08:31.383 回答