IQueryable和IEnumerable有什么区别?
我对这个区别感到困惑。 对.Net来说相当新,我知道我可以使用Linq扩展来查询IEnumerables
。 那么这个IQueryable
是什么?它有什么不同?
另请参见IQueryable [T]和IEnumerable [T]之间的区别是什么? 与这个问题重叠。
IEnumerable<T>
表示IEnumerable<T>
的正向游标。 .NET 3.5添加了扩展方法,其中包括像Where
和First
这样的LINQ standard query operators
,以及任何需要Func<T>
谓词或匿名函数的运算符。
IQueryable<T>
实现了相同的LINQ标准查询操作符,但接受谓词和匿名函数的Expression<Func<T>>
。 Expression<T>
是一个编译的expression式树,该方法的分解版本(如果您愿意的话,可以是“半编译的”)可以由查询的提供者分析并相应地使用。
例如:
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式树( Expression<Func<Person, bool>>
),它可以被认为是'Age'属性> 18“。
这允许像LINQ-to-SQL这样的东西存在,因为它们可以parsingexpression式树并将其转换为等效的SQL。 而且由于在枚举IQueryable
(它实现了IEnumerable<T>
)之前,提供者不需要执行,所以它可以组合多个查询运算符(在上面的示例Where
和FirstOrDefault
)来更明智地select如何执行对底层数据源的整个查询(如在SQL中使用SELECT TOP 1
)。
看到:
- .NET标准查询运算符
在现实生活中,如果你正在使用像LINQ到SQL这样的ORM
- 如果您创build一个
IQueryable
,那么查询可能会转换为SQL并在数据库服务器上运行 - 如果您创build了一个
IEnumerable
,那么在运行查询之前,所有的行将被作为对象拉入内存中。
在这两种情况下,如果您不调用ToList()
或ToArray()
那么每次使用时都会执行查询,因此,例如,您有一个IQueryable
并从中填充4个列表框,则查询将会对数据库运行4次。
另外如果你扩展你的查询:
q.Select(x.name = "a").ToList()
然后用一个IQueryable
生成的SQL将包含where name = "a"
,但是使用IEnumerable
更多的angular色将从数据库中拉出,然后x.name = "a"
检查将由.NET完成。
“主要区别在于为IQueryable定义的扩展方法使用Expression对象而不是Func对象,这意味着它接收的委托是expression式树而不是调用方法。IEnumerable对于使用内存集合非常有用,但IQueryable允许对于远程数据源,如数据库或Web服务“
来源: 这里
IEnumerable的
IEnumerable<Employee> emp = ent.Employees; IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
IQueryable的
IQueryable<Employee> emp = ent.Employees; IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
所以“IQueryable”和“IEnumerable”之间的基本区别在于filter逻辑的执行位置。 一个在客户端执行,另一个在数据库上执行。
还要注意“IQueryable”接口inheritance自“IEnumerable”,所以无论“IEnumerable”能做什么,“IQueryable”也可以做到。
IEnumerable IEnumerable最适合使用内存中的集合。 IEnumerable不移动项目之间,它只是向前收集。
IQueryable IQueryable最适合于远程数据源,如数据库或Web服务。 IQueryable是一个非常强大的function,可以实现各种有趣的延迟执行scheme(如基于分页和组合的查询)。
因此,当您只需遍历内存集合时,使用IEnumerable,如果您需要对集合(如“数据集”和其他数据源)执行任何操作,请使用IQueryable
主要区别在于IEnumerable会一直枚举所有的元素,而IEqueryable会枚举元素,甚至根据查询来做其他事情。 查询是一个expression式(.Net代码的数据表示),IQueryProvider必须探索/解释/编译/任何为了生成结果。
查询expression式有两个优点。
第一个优点是优化。 由于修饰符(如“Where”)包含在查询expression式中,因此IQueryProvider可以应用其他不可能的优化。 提交者可以使用散列表来定位具有给定键的项目,而不是返回所有元素,然后抛弃其中的大部分元素。
第二个优点是灵活性。 由于expression式是可探测的数据结构,因此可以将查询序列化并将其发送到远程机器(例如,linq-to-sql)。
IQueriable与IEnumerable相同,但它也提供了额外的function来实现Linq的自定义查询。 这里是对MSDN的描述: http : //msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx
首先在System.Collections命名空间中findIEnumerable,而在System.Linq命名空间中findIQueryable。 如果您在查询内存集合(如List,Array集合等)中的数据时使用IEnumerable并且在从外存(如远程数据库,服务)集合中查询数据时,请使用IQueryable。 因为在从数据库查询数据时,IEnumerable执行在服务器端select查询,在客户端加载内存中的数据,然后过滤数据。 因此做更多的工作,变得缓慢。 在从数据库查询数据的同时,IQueryable使用所有filter在服务器端执行select查询。 因此,工作量减less,速度变快。