1

从数据库中获取短语后,我试图找到包含短语中所有单词的所有元素:

string text = "ab cd 23";//the element prop2 must have all 3 word regardless their order
var q = from c in db.myTable
where c.Prop1 == "value"
select c;
string[] strings = text.Split(' ');
foreach(string word in strings)
{
       int cnt = q.Count();//first time cnt = 1500 which is correct 
       q = q.Where(c => c.Prop2.Contains(word));// Prop2 is a string
       cnt = q.Count();//first time cnt = 460
}

在此之前一切都很好:

foreach(string word in strings)// second time
{
       int cnt = q.Count();//second time cnt = 14 ??
       q = q.Where(c => c.Prop2.Contains(word));
       cnt = q.Count();//first time cnt = 2
}

在第二个循环中不做任何事情,元素计数会发生变化,这应该只返回包含所有单词的元素,但它只返回最后一个元素,第三个循环是无用的,没有任何变化

我很抱歉长 Q,但我是 linq 的新手

4

1 回答 1

3

我认为这可能是可怕的“修改关闭”错误。创建word循环变量的临时副本,并在查询中使用它。

foreach(string word in strings) {
    var tmp = word;
    int cnt = q.Count();
    q = q.Where(c => c.Prop2.Contains(tmp));
    cnt = q.Count();//first time cnt = 460
}

您应该避免在 LINQ 表达式中使用循环变量,除非您立即“实现”它们(即调用ToList()ToArrayFirst()SingleOrDefault等)。当您需要使用循环变量的值时,请制作一个临时副本。原因是 LINQ 推迟了查询的执行,所以当查询被执行时,循环变量的值发生了变化,你的结果会出乎意料地改变。

于 2012-06-08T03:17:33.867 回答