1

I'm trying to find all element that contains all words in a phrase after geting them from database:

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 } 

everything is alright till this:

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 } 

without doing anything at the second loop the element count changes furthermore this should return only element with all the words but it return element with just the last one and the third loop is useless changes nothing

I'm sorry for the long Q but I'm new to linq

1 Answer 1

3

I think this may be the dreaded "modified closure" error. Create a temporary copy of the word loop variable, and use it instead in your queries.

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 } 

You should avoid using loop variables in LINQ expressions, unless you "materialize" them right away (i.e. call ToList(), ToArray, First(), SingleOrDefault, etc.) When you need to use the value of your loop variable, make a temporary copy. The reason is that LINQ defers execution of your query, so when by the time the query gets executed the value of the loop variable has changed, your results will change unexpectedly.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.