为什么我们需要使用 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

- DbSet Is an 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.

通过反射查询它们