LINQ bites back
by bhartsock on Aug.07, 2008, under .NET, Programming
Today I found some odd behavior when working with LINQ. It is hard to describe, so here is the code.
public void Foo(IEnumerable<string> strings) { IEnumberable<string> stringsInDb = strings.Where(s => this.QueryTheDbAndTakeALongTime(s)); foreach(string str in stringsInDb) { //Where clause in LINQ is actually executed } foreach(string str in stringsInDb) { //Where clause in LINQ is actually executed AGAIN } }
Luckily, some unit tests detected this behavior. It actually isn’t surprising when you think about it though. The proper thing to do for this case is actually call ToList() after the Where().
IEnumberable<string> stringsInDb = strings.Where(s => this.QueryTheDbAndTakeALongTime(s)).ToList();
Don’t let this behavior bite you.
August 9th, 2008 on 7:51 pm
This is because of deferred execution, and the fact that unless you call an enumerator, it will always re-execute the linq query. You can read more about this at:
Using LINQ to Convert an IENumerable to a List
August 11th, 2008 on 4:56 pm
Ya. A co-worker informed me of this behavior, which makes complete sense. It is just a little scary for the ignorant, because it allows code to be written that works yet behaves differently than might be expected.
August 27th, 2008 on 2:57 pm
LINQ….. *sigh*