2015-03-02 133 views
1

此代码会导致NotSupportedException。为什么我们需要使用AsEnumerable()方法?

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

- DbSet Is an IEnumerable

那么,为什么我们需要使用AsEnumerable()方法?

+1

为什么在使用'var detailList = context.Details.Where(x => x.Code.ToString()==“00101”)时使用了反射。 – 2015-03-02 14:51:57

回答

7

DbSet也是IQueryable

IQueryable拥有自己的一套LINQ扩展方法,可将表达式树转换为SQL,并且不支持反射。

通过调用AsEnumerable(),您将表达式的编译时类型更改为IEnumerable<T>,强制扩展方法绑定到标准LINQ。

如果您希望在服务器上运行查询,则应该构建表达式树而不是使用反射。

+0

你的解释不是很理解(很多条款),但我喜欢它(+1)。新东西不是标准答案。 – 2015-03-02 15:01:48

3

第一个查询尝试让查询提供程序将查询转换为SQL并对数据库执行查询。它无法创建有效的数据库查询,因此它会因提到的错误而失败。

使用AsEnumerable类型查询作为IEnumerable<T>,而不是IQueryable<T>,静态的,因此结束调用的LINQ对象版本的查询方法,拉动整个表装入存储器中,然后进行内的所有的操作的应用程序。

0

当您查询IQueryable<T>时,您的方法将通过Expression Tree转换为SQL。 AsEnumerable将编译时间类型更改为IEnumerable<T>,并将数据库中的所有实体存入内存,您可以通过LINQ to Objects通过反射查询它们。