Reputation: 22954
I have an IQueryable
custs, a Customer
cust, a CustomerComparer
custCp which implements IEqualityComparer
.
When I call custs.Contains(cust, custCp)
I get an exception:
System.NotSupportedException: Unsupported overload used for query operator 'Contains'
But when I call custs.AsEnumerable().Contains(cust,custCp)
it works. Can anyone explain why?
Upvotes: 1
Views: 977
Reputation: 180867
An operation on an IQueryable
(in the case of Linq to Entities) is translated to SQL and executed in the database. Since you have an IEqualityComparer
written in C#, the comparer can't be translated to SQL and the overload can't be supported.
When you translate it to an IEnumerable
using AsEnumerable()
, all the data is transferred from the database to memory, where the overload can be easily supported. The downside of course being that you're transferring more data than necessary (potentially the whole table) to have it filtered in memory.
Upvotes: 3
Reputation: 50276
IQueryable
is implemented by query providers and under the hood translated into something the target system can understand. For example, IQueryable.Contains
might be translated to a x IN y
SQL expression.
On the other hand, IEnumerable
is not translated like that. Its Contains
works on anything that implements IEnumerable
properly.
Using the IQueryable
operators are executed server-side and therefore will gain you some performance as the query is executed remotely, whereas IEnumerable
is executed locally (client-side). This means that if you were to get a database table, convert it to enumerable and then apply Contains
on it, the whole table needs to be downloaded to your computer to be enumerated.
Upvotes: 1