IQueryable和IEnumerable之间有什么区别

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


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


IEnumerable<T>表示的一个只进光标T 。 .NET 3.5添加了扩展方法,其中包括像WhereFirst这样的LINQ standard query operators ,任何需要谓词或匿名函数的运算符都采用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>> ),可以将其视为“Age'属性> 18”。

这允许像LINQ-to-SQL这样的东西存在,因为它们可以解析表达式树并将其转换为等效的SQL。 并且因为提供者在枚举IQueryable之前不需要执行(毕竟它实现了IEnumerable<T> ),所以它可以组合多个查询运算符(在上面的示例WhereFirstOrDefault )以更明智地选择如何执行对底层数据源的整个查询(如在SQL中使用SELECT TOP 1 )。

看到:

  • .NET标准查询操作符

  • 在现实生活中,如果您使用的是像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完成。


    “主要的区别在于,对于IQueryable的取表达式定义的扩展方法的对象,而不是函数功能对象,这意味着其接收到委托的表达式树代替调用方法的。IEnumerable的非常适合在内存中的集合工作,但IQueryable的允许对于远程数据源,如数据库或Web服务“

    来源:这里

    链接地址: http://www.djcxy.com/p/21249.html

    上一篇: What's the difference between IQueryable and IEnumerable

    下一篇: What is the difference between IQueryable<T> and IEnumerable<T>?