IQueryable的Contains()和IEnumerable的Contains()之间有什么区别?

时间:2013-03-15 13:48:04

标签: linq ienumerable iqueryable iequalitycomparer

我有一个IQueryable个cust,一个Customer cust,一个CustomerComparer custCp,它实现了IEqualityComparer

当我致电custs.Contains(cust, custCp)时,我得到一个例外:

System.NotSupportedException: Unsupported overload used for query operator 'Contains'

但是当我打电话给custs.AsEnumerable().Contains(cust,custCp)时,它有效。任何人都可以解释原因吗?

2 个答案:

答案 0 :(得分:2)

IQueryable上的操作(在Linq to Entities的情况下)被转换为SQL并在数据库中执行。由于您使用C#编写了IEqualityComparer,因此无法将比较器转换为SQL并且不能支持重载。

使用IEnumerable将其转换为AsEnumerable()时,所有数据都会从数据库传输到内存,从而可以轻松支持过载。当然,缺点是您传输的数据超出了必要的数量(可能是整个表格),以便在内存中进行过滤。

答案 1 :(得分:1)

IQueryable由查询提供程序实现,引擎转换为目标系统可以理解的内容。例如,IQueryable.Contains可能会被转换为x IN y SQL表达式。

另一方面,IEnumerable不是那样翻译的。它的Contains适用于任何正确实现IEnumerable的内容。

使用IQueryable运算符在服务器端执行,因此在远程执行查询时会获得一些性能,而IEnumerable在本地执行(客户端)。这意味着如果您要获取数据库表,将其转换为可枚举,然后在其上应用Contains需要将整个表下载到您的计算机中进行枚举。