【发布时间】:2015-09-17 14:28:50
【问题描述】:
我了解 IQueryable 和 IEnumerable 之间的主要区别。 IQueryable 在数据库中执行查询并返回过滤后的结果,而 IEnumerable 将完整的结果集带入内存并在那里执行过滤查询。
我不认为使用扩展方法来查询变量的初始分配会导致它像 IQueryable 一样在数据库中执行,但我只是想确定一下。
这段代码会导致从数据库中返回People的完整结果集,然后在内存中进行过滤:
(上下文中的 People 属性是 DbSet 类型)
IEnumerable<Person> people = context.People;
Person person = people.Where(x => x.FirstName == "John");
即使我在将项目分配给我的变量之前添加下面的过滤作为扩展方法,我假设这段代码应该与上面的代码一样工作,并在过滤之前将完整的结果集带回内存对吧?
Person person = context.People.Where(x => x.FirstName == "John");
编辑:
感谢大家的回复。我修改了代码示例以显示我的意思(删除了第二段代码中的 IEnumerable)。
另外,澄清一下,context.People 是 DbSet 类型,它实现了 IQueryable 和 IEnumerable。所以我实际上不确定调用了哪个 .Where 方法。 IntelliSense 告诉我它是 IQueryable 版本,但这可以信任吗?直接使用上下文的 DbSet 时总是这样吗?
【问题讨论】:
-
那么
context.People的类型是什么?我怀疑它是IQueryable<Person>,在这种情况下不,它们不一样——你的第一个代码将调用Enumerable.Where,你的第二个代码将调用Queryable.Where。 -
假设
context.People是IQueryable而不是IEnumerable,那么第二个选项会更快,因为您的数据库将返回更少的数据。将Where应用于可查询时,您仍然有可查询 -
你的理解有误。是 IQueryable 的实现以及使用它的代码决定了它的行为。该接口仅定义了支持针对不同提供程序的类似 linq 操作的类型的形状。
-
差异的原因是您将
people分配给IEnumerable<Person>。尝试使用var或IQueryable<Person>,结果会有所不同。
标签: c# linq ienumerable iqueryable