使用扩展方法查询IEnumerable是否等同于使用IQueryable ?
本文关键字:等同于 是否 IQueryable 查询 扩展 方法 IEnumerable | 更新日期: 2023-09-27 18:13:13
我理解IQueryable和IEnumerable之间的主要区别。IQueryable在数据库中执行查询并返回过滤后的结果,而IEnumerable将完整的结果集放入内存并在内存中执行过滤查询。
我不认为使用扩展方法来查询变量的初始赋值会导致它像IQueryable一样在数据库中执行,但我只是想确保。
这段代码将导致从数据库返回person的完整结果集,然后在内存中进行过滤:
(上下文的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)。
同时,为了澄清上下文。People的类型是DbSet,它同时实现了IQueryable和IEnumerable。所以我不确定哪个。where方法被调用了。智能感知告诉我这是可查询的版本,但这可以信任吗?当直接使用上下文的DbSet时,情况总是这样吗?
IEnumerable<Person> people = context.People;
Person person = people.Where(x => x.FirstName == "John");
…将执行IEnumerableFunc<TSource, bool> predicate
参数,强制在内存中进行过滤。
IEnumerable<Person> people = context.People.Where(x => x.FirstName == "John");
…将执行IQueryableExpression<Func<TSource, bool>> predicate
参数。请注意,这是一个表达式,而不是一个委托,它允许它将where
条件转换为数据库条件。
所以你调用的扩展方法是有区别的
IQueryable
- 以目标语言(例如SQL)从累积的表达式生成查询
- 查询被执行,通常在数据库上,
- 结果被转换回c#对象。
IEnumerable
- 这些函数中的c#代码被执行。
这两者很容易混淆,因为:
- 都有相似名字的扩展函数,
- lambda语法对于表达式和函数是相同的-所以你不能区分它们,
-
使用"var"来声明变量删除了数据类型(通常是使用哪个接口的唯一线索)。
IQueryable<int> a; IEnumerable<int> b; int x1 = a.FirstOrDefault(i => i > 10); // Expression passed in int x2 = b.FirstOrDefault(i => i > 10); // Function passed in
具有相同名称的扩展方法通常做相同的事情(因为它们是这样写的),但有时它们不是。
所以答案是:不,它们不相等