IQueryable和IEnenable的区别是什么?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (15)

我对这个区别感到困惑。对.Net来说相当新,我知道我可以IEnumerables使用Linq扩展进行查询。那么这是什么IQueryable?它有什么不同?

提问于
用户回答回答于

IEnumerable<T>代表仅前向游标T。.NET 3.5添加的扩展方法,其中包括的LINQ standard query operatorsWhereFirst,与需要谓词或匿名函数采取任何操作符Func<T>

IQueryable<T>实现相同的LINQ标准查询操作符,但接受Expression<Func<T>>谓词和匿名函数。Expression<T>是一个编译的表达式树,该方法的分解版本(如果您愿意的话,可以是“半编译的”),可以由查询的提供者分析并相应地使用。

例如:

IEnumerable<Person> people = GetEnumerablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

IQueryable<Person> people = GetQueryablePeople();
Person person = people.Where(x => x.Age > 18).FirstOrDefault();

在第一个块中,x => x.Age > 18是一个匿名方法(Func<Person, bool>),它可以像任何其他方法一样执行。Enumerable.Where将为每个人执行一次yield方法,返回方法返回的值true

在第二个块中,x => x.Age > 18是一个表达式树(Expression<Func<Person, bool>>),它可以被认为是“年龄”属性> 18“。

这允许像LINQ-to-SQL这样的东西存在,因为它们可以解析表达式树并将其转换为等效的SQL。而且因为直到提供商并不需要执行IQueryable枚举(它实现了IEnumerable<T>,毕竟),它可以合并多个查询运算符(在上面的例子中WhereFirstOrDefault)就如何打击基础数据执行整个查询更明智的选择源代码(如SELECT TOP 1在SQL中使用)。

用户回答回答于

在现实生活中,如果使用的是像LINQ到SQL这样的ORM

  • 如果创建了一个IQueryable,那么查询可能会转换为sql并在数据库服务器上运行
  • 如果创建一个IEnumerable,那么在运行查询之前,所有行都将作为对象拉入内存。

在这两种情况下,如果不调用ToList()ToArray()然后查询将在每次使用时执行,因此,例如,有一个IQueryable并且从中填充4个列表框,则查询将针对数据库运行4次。

同样,如果你扩展你的查询:

q.Select(x.name = "a").ToList()

然后用一个IQueryable生成的SQL将包含where name = "a",但与IEnumerable更多的角色将被从数据库拉回来,然后x.name = "a"检查将由.NET完成。

扫码关注云+社区