IQueryable <T>和IEnumerable <T>有什么区别?
IQueryable<T>
和IEnumerable<T>
什么区别?
另请参见与此问题重叠的IQueryable和IEnumerable之间的区别。
首先, 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
。
主要区别在于用于IQueryable<T>
的LINQ运算符使用Expression
对象而不是委托,这意味着它接收的自定义查询逻辑(例如谓词或值选择器)以表达式树的形式而不是委托给方法。
IEnumerable<T>
非常适合用于在内存中迭代的序列,但是 IQueryable<T>
允许像远程数据源(如数据库或Web服务)的内存不足。 查询执行:
在查询的执行将“在进行中”的情况下 ,通常所需要的是执行查询的每个部分的代码(作为代码)。
如果执行将在进程外执行,则查询的逻辑必须用数据表示,以便LINQ提供程序可以将其转换为适用于内存不足执行的适当形式 - 无论是LDAP查询, SQL或其他。
更多信息:
IEnumerable<T>
和IQueryable<T>
IEnumerable<T>
vs IQueryable<T>
” IEnumerable
, IQueryable
, IObservable
和IQbservable
这是我的Facebook页面上的一个很好的视频,演示了这些界面如何不同,值得一看。
下面是一个长的描述性答案。
要记住的第一个要点是IQueryable
接口继承自IEnumerable
,所以无论IEnumerable
能做什么, IQueryable
都可以。
有很多不同之处,但让我们讨论一下造成最大差异的一个重大差异。 当您的集合使用LINQ
或实体框架加载并且您想要对集合应用过滤器时, IEnumerable
接口很有用。
考虑下面使用IEnumerable
与实体框架的简单代码。 它使用Where
过滤器来获取EmpId
为2
记录。
EmpEntities ent = new EmpEntities();
IEnumerable<Employee> emp = ent.Employees;
IEnumerable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
这是筛选器在IEnumerable
代码所在的客户端执行的位置。 换句话说,所有数据都是从数据库中获取的,然后在客户端扫描并获得EmpId
为2
的记录。
但现在看到下面的代码,我们已经将IEnumerable
更改为IQueryable
。 它在服务器端创建一个SQL查询,只有必要的数据被发送到客户端。
EmpEntities ent = new EmpEntities();
IQueryable<Employee> emp = ent.Employees;
IQueryable<Employee> temp = emp.Where(x => x.Empid == 2).ToList<Employee>();
所以IQueryable
和IEnumerable
之间的区别在于过滤器逻辑被执行的地方。 一个在客户端执行,另一个在数据库上执行。
因此,如果只处理内存中的数据收集, IEnumerable
是一个不错的选择,但是如果您想查询与数据库相关的数据收集,那么IQueryable是一个更好的选择,因为它可以减少网络流量并使用SQL语言的强大功能。
上一篇: What is the difference between IQueryable<T> and IEnumerable<T>?
下一篇: Memory allocation of base class and derived class constructor