score:9

Accepted answer

The difference is that in the first case, var will be an IQueryable<T> - which means your Where call will be to Queryable.Where (after converting your lambda expression to an expression tree). The filter ends up being executed in the database, where I suspect your field is case-insensitive (and so searching is case-insensitive).

In the second case, you've got an IEnumerable<T>, so your Where call will be to Enumerable.Where (after converting your lambda expression to a delegate). The filter ends up being executed in .NET code instead - where Contains is always case-sensitive.

Basically, LINQ is a leaky abstraction - yes, it would be lovely if the same filter gave the same results in all situations, but that's unrealistic. Learn where the leaks are, and act accordingly - LINQ is still a huge boon :)

score:7

Your result variable is not an IEnumerable - it is an IQueryable.

The result is changing when you manually change the type to IEnumerablesince you now do the following Contains query with Linq to Objects and not on the database with Linq to Entities (or Linq to SQL).

With IEnumerable your query is using your lambda expression, bringing each result from the DB into memory and executing the case sensitive Contains() extension method.

With IQueryable your query is using an expression tree and will try to create a corresponding database query with your Contains query which happens to be case insensitive (most likely a SQL LIKE query).

Just making the implicit type explicit as IQueryable will fix your problem.


Related Articles