为什么我们需要使用 AsEnumerable() 方法?
why we need to use AsEnumerable() method?
此代码导致 NotSupportedException。
var detailList = context.Details.Where(x => x.GetType().GetProperty("Code").GetValue(x,null).ToString() == "00101").ToList();
但是这段代码有效。
var detailList = context.Details.AsEnumerable().Where(x => x.GetType().GetProperty("Code").GetValue(x,null).ToString() == "00101").ToList();
MSDN 说:
- AsEnumerable() Returns the input typed as IEnumerable
那么为什么我们需要使用 AsEnumerable() 方法?
DbSet
也是 IQueryable
.
IQueryable
有自己的一套LINQ扩展方法,将表达式树翻译成SQL,不支持反射。
通过调用 AsEnumerable()
,您将表达式的编译时类型更改为 IEnumerable<T>
,强制扩展方法绑定到标准 LINQ 方法。
如果您更喜欢 运行 在服务器上查询,您应该构建表达式树而不是使用反射。
第一个查询尝试让查询提供程序将查询翻译成 SQL 并针对数据库执行。它无法创建有效的数据库查询,因此失败并出现上述错误。
静态地使用 AsEnumerable
将查询键入 IEnumerable<T>
,而不是 IQueryable<T>
,因此最终调用 LINQ to objects 版本的查询方法,拉整个 table 到内存中,然后执行应用程序中的所有操作。
当您查询 IQueryable<T>
时,您的方法会通过 Expression Tree
转换为 SQL。 AsEnumerable
将编译时类型更改为 IEnumerable<T>
并将数据库中的所有实体放入内存,您可以在内存中通过 LINQ to Objects
.
通过反射查询它们
此代码导致 NotSupportedException。
var detailList = context.Details.Where(x => x.GetType().GetProperty("Code").GetValue(x,null).ToString() == "00101").ToList();
但是这段代码有效。
var detailList = context.Details.AsEnumerable().Where(x => x.GetType().GetProperty("Code").GetValue(x,null).ToString() == "00101").ToList();
MSDN 说:
- AsEnumerable() Returns the input typed as IEnumerable
那么为什么我们需要使用 AsEnumerable() 方法?
DbSet
也是 IQueryable
.
IQueryable
有自己的一套LINQ扩展方法,将表达式树翻译成SQL,不支持反射。
通过调用 AsEnumerable()
,您将表达式的编译时类型更改为 IEnumerable<T>
,强制扩展方法绑定到标准 LINQ 方法。
如果您更喜欢 运行 在服务器上查询,您应该构建表达式树而不是使用反射。
第一个查询尝试让查询提供程序将查询翻译成 SQL 并针对数据库执行。它无法创建有效的数据库查询,因此失败并出现上述错误。
静态地使用 AsEnumerable
将查询键入 IEnumerable<T>
,而不是 IQueryable<T>
,因此最终调用 LINQ to objects 版本的查询方法,拉整个 table 到内存中,然后执行应用程序中的所有操作。
当您查询 IQueryable<T>
时,您的方法会通过 Expression Tree
转换为 SQL。 AsEnumerable
将编译时类型更改为 IEnumerable<T>
并将数据库中的所有实体放入内存,您可以在内存中通过 LINQ to Objects
.