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
}

2番目のループで何もしないと、要素数がさらに変更されます。これは、すべての単語を含む要素のみを返す必要がありますが、最後の1つだけの要素を返し、3番目のループは役に立たず、何も変更しません

長い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 に答える