此代码导致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()方法?
答案 0 :(得分:7)
DbSet
也是IQueryable
。
IQueryable
有自己的一组LINQ扩展方法,可以将表达式树转换为SQL,并且不支持反射。
通过调用AsEnumerable()
,可以将表达式的编译时类型更改为IEnumerable<T>
,从而强制扩展方法绑定到标准LINQ。
如果您更喜欢在服务器上运行查询,则应构建表达式树而不是使用反射。
答案 1 :(得分:3)
第一个查询尝试让查询提供程序将查询转换为SQL并对数据库执行它。它无法创建有效的数据库查询,因此失败并显示错误。
使用AsEnumerable
静态地将查询键入为IEnumerable<T>
而不是IQueryable<T>
,因此最终调用LINQ to对象版本的查询方法,拉动整个将表存入内存,然后执行应用程序中的所有操作。
答案 2 :(得分:0)
当您查询IQueryable<T>
时,您的方法会通过Expression Tree
转换为SQL。 AsEnumerable
将编译时类型更改为IEnumerable<T>
并将数据库中的所有实体放入内存,您可以通过LINQ to Objects
通过反射查询它们。