IQueryable和IEnumerable之间有什么区别

Jam*_*Hay 148 linq ienumerable .net-3.0 iqueryable

我对这种差异感到困惑.作为.Net的新手,我知道我可以IEnumerables使用Linq扩展进行查询.那么这是什么IQueryable以及它有何不同?


另请参见IQueryable [T]和IEnumerable [T]之间的区别是什么?与这个问题重叠.

Ric*_*lay 185

IEnumerable<T>表示只有前进的游标T..NET 3.5添加了包含LINQ standard query operators类似的扩展方法,Where以及First任何需要谓词或匿名函数的运算符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();
Run Code Online (Sandbox Code Playgroud)

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

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

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

看到:


Ian*_*ose 80

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

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

在这两种情况下,如果你不调用a ToList(),ToArray()那么每次使用时都会执行查询,所以,比方说,你有一个IQueryable并从中填充4个列表框,然后查询将对数据库运行4次.

此外,如果您扩展您的查询:

q.Select(x.name = "a").ToList()
Run Code Online (Sandbox Code Playgroud)

然后用IQueryable生成的SQL将包含where name = "a",但是有IEnumerable更多的角色将从数据库中撤回,然后x.name = "a"检查将由.NET完成.


Gab*_*abe 36

"主要区别在于为IQueryable定义的扩展方法采用Expression对象而不是Func对象,这意味着它接收的委托是表达式树而不是要调用的方法.IEnumerable非常适合处理内存中的集合,但IQueryable允许用于远程数据源,如数据库或Web服务"

来源:这里


Tal*_*lha 18

IEnumerable IEnumerable最适合处理内存中的集合.IEnumerable不会在项目之间移动,它只是前向收集.

IQueryable IQueryable最适合远程数据源,如数据库或Web服务.IQueryable是一个非常强大的功能,可以实现各种有趣的延迟执行方案(如分页和基于组合的查询).

因此,当您必须简单地遍历内存中的集合时,使用IEnumerable,如果您需要对数据集和其他数据源等集合进行任何操作,请使用IQueryable


Cra*_*ney 9

主要区别在于IEnumerable将始终枚举其所有元素,而IEqueryable将根据查询枚举元素,甚至执行其他操作.查询是一个Expression(.Net代码的数据表示),IQueryProvider必须探索/解释/编译/以生成结果.

拥有查询表达式有两个优点.

第一个优点是优化.由于查询表达式中包含"Where"等修饰符,因此IQueryProvider可以应用其他不可能的优化.由于'Where'子句,提供者可以使用哈希表来查找具有给定键的项目,而不是返回所有元素然后丢弃大部分元素.

第二个优点是灵活性.因为表达式是可探索的数据结构,所以您可以执行诸如序列化查询并将其发送到远程计算机(例如,linq-to-sql)之类的操作.