IQueryable<T>和IEnumerable<T>之间的区别是什么?


另见IQueryable和IEnumerable之间的区别是什么,与这个问题重叠。


当前回答

以下是我在类似的帖子(关于这个话题)上所写的内容。(不,我通常不引用自己的话,但这些都是非常好的文章。)

这篇文章很有帮助: LINQ-to-SQL中的IQueryable和IEnumerable。

引用那篇文章,“根据MSDN文档,对IQueryable调用通过构建内部表达式树来操作。 这些扩展IQueryable(Of T)的方法不直接执行任何查询。相反,它们的功能是构建Expression对象,该对象是表示累积查询的表达式树。“‘

Expression trees are a very important construct in C# and on the .NET platform. (They are important in general, but C# makes them very useful.) To better understand the difference, I recommend reading about the differences between expressions and statements in the official C# 5.0 specification here. For advanced theoretical concepts that branch into lambda calculus, expressions enable support for methods as first-class objects. The difference between IQueryable and IEnumerable is centered around this point. IQueryable builds expression trees whereas IEnumerable does not, at least not in general terms for those of us who don't work in the secret labs of Microsoft.

下面是另一篇非常有用的文章,从推和拉的角度详细介绍了两者的区别。(通过“push”和“。“拉”,我指的是数据流的方向。用于。net和c#的响应式编程技术

这是一篇非常好的文章,详细介绍了语句lambdas和表达式lambdas之间的区别,并更深入地讨论了表达式树的概念:重访c#委托、表达式树和lambda语句与lambda表达式。”

其他回答

IEnumerable: IEnumerable最适合使用内存中的集合(或本地查询)。 IEnumerable不能在项目之间移动,它只是向前的集合。

这个IQueryable: IQueryable最适合远程数据源,如数据库或web服务(或远程查询)。 IQueryable是一个非常强大的特性,它支持各种有趣的延迟执行场景(比如分页和基于组合的查询)。

所以当你必须简单地遍历内存中的集合时,使用IEnumerable,如果你需要对集合做任何操作,如Dataset和其他数据源,使用IQueryable

我们使用IEnumerable和IQueryable来操作从数据库中检索的数据。IQueryable继承自IEnumerable,所以IQueryable包含了IEnumerable的所有特性。IQueryable和IEnumerable之间的主要区别是IQueryable使用过滤器执行查询,而IEnumerable先执行查询,然后根据条件过滤数据。

更详细的区别如下:

IEnumerable

IEnumerable在系统中存在。集合名称空间 IEnumerable在服务器端执行选择查询,在客户端加载内存中的数据,然后筛选数据 IEnumerable适用于从List、Array等内存集合中查询数据 IEnumerable有利于LINQ to Object和LINQ to XML查询

这个IQueryable

系统中存在IQueryable功能。Linq命名空间 IQueryable在服务器端执行一个带有所有过滤器的“选择查询” IQueryable适用于从内存外(如远程数据库,服务)集合中查询数据 IQueryable有利于LINQ到SQL的查询

所以IEnumerable通常用于处理内存中的集合,而IQueryable通常用于操作集合。

首先,IQueryable<T>扩展了IEnumerable<T>接口,所以任何你可以用“普通”IEnumerable<T>做的事情,你也可以用IQueryable<T>做。

IEnumerable<T>只有一个GetEnumerator()方法,该方法返回一个Enumerator<T>,为此您可以调用它的MoveNext()方法来遍历T的序列。

IQueryable<T>具有而IEnumerable<T>所没有的两个特殊属性——一个指向查询提供程序(例如,LINQ to SQL提供程序),另一个指向表示IQueryable<T>对象的查询表达式,作为一个运行时可遍历的抽象语法树,可以被给定的查询提供程序理解(在大多数情况下,你不能在不抛出异常的情况下将LINQ to SQL表达式提供给LINQ to Entities提供程序)。

表达式可以是对象本身的常量表达式,也可以是由查询操作符和操作数组成的更复杂的树。查询提供程序的IQueryProvider.Execute()或IQueryProvider.CreateQuery()方法通过传递给它的表达式被调用,然后分别返回一个查询结果或另一个IQueryable方法。

以下是我在类似的帖子(关于这个话题)上所写的内容。(不,我通常不引用自己的话,但这些都是非常好的文章。)

这篇文章很有帮助: LINQ-to-SQL中的IQueryable和IEnumerable。

引用那篇文章,“根据MSDN文档,对IQueryable调用通过构建内部表达式树来操作。 这些扩展IQueryable(Of T)的方法不直接执行任何查询。相反,它们的功能是构建Expression对象,该对象是表示累积查询的表达式树。“‘

Expression trees are a very important construct in C# and on the .NET platform. (They are important in general, but C# makes them very useful.) To better understand the difference, I recommend reading about the differences between expressions and statements in the official C# 5.0 specification here. For advanced theoretical concepts that branch into lambda calculus, expressions enable support for methods as first-class objects. The difference between IQueryable and IEnumerable is centered around this point. IQueryable builds expression trees whereas IEnumerable does not, at least not in general terms for those of us who don't work in the secret labs of Microsoft.

下面是另一篇非常有用的文章,从推和拉的角度详细介绍了两者的区别。(通过“push”和“。“拉”,我指的是数据流的方向。用于。net和c#的响应式编程技术

这是一篇非常好的文章,详细介绍了语句lambdas和表达式lambdas之间的区别,并更深入地讨论了表达式树的概念:重访c#委托、表达式树和lambda语句与lambda表达式。”

在现实生活中,如果您正在使用LINQ-to-SQL之类的ORM

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

在这两种情况下,如果你不调用ToList()或ToArray(),那么查询将在每次使用它时执行,所以,比如说,你有一个IQueryable<T>,你从它填充4个列表框,那么查询将对数据库运行4次。

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

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

然后使用IQueryable生成的SQL将包含" where name = " a ",但是使用IEnumerable会从数据库中拉回更多的角色,然后. net将完成x.name = " a "检查。