IQueryable和IEnumerable以及AsEnumerable()和ToList()的区别

注意:本文背景为 Linq to sql 。文中ie指代IEnumerableiq指代IQueryable

IQueryable 和 IEnumerable 的区别

  • IQueryable
    延时执行;扩展方法接受的是Expression(必须要能转成sql,否则报错)
  • IEnumerable
    延时执行;扩展方法接受的是Func(C#语法)

AsEnumerable() 和 ToList() 的区别

  • ToList()
    立即执行,加载数据到内存中。
  • AsEnumerable()
    延时执行,真正使用时才加载数据。

对IQueryable对象使用AsEnumerable()后,仍然是延时执行,不过此时对象本质已经变了。

前面已经说了IEnumerable的扩展方法接受的是Func(C#语法),当ie对象(iq转变)真正使用时,会有2个步骤:

  1. 它会把iq对象(转变之前的)的扩展方法翻译成sql语句,查询出数据加载到内存中,变为ie对象;
  2. 此时再把ie对象(转变之后的)的扩展方法,使用C#求解,得到最终结果。

例如:

iq对象的Skip、Take方法,会被翻译成sql,在数据库里执行取出最终结果。

而ie对象的Skip、Take方法,则会取出全部数据到内存中,在内存中执行Skip、Take,会耗费大量资源。

误区

  • 误区1:对 iq对象 和 ie对象 使用foreach时,对于循环的每项都要查询数据库。

    错误!
    foreach针对的是数据集整体对象(枚举器?)。当使用foreach时,不管是iq对象还是ie对象,它们都是查询数据库一次,然后开始循环,直至循环结束。不过,当后续再次使用iq对象或ie对象的具体数据时,它们仍然会再次查询数据库。

结论

假设我们把最终数据之前的数据称为中间数据,那么:

  1. 中间数据只是作为条件筛选,需要的只是层层筛选之后的最终数据时,应该继续使用IQueryable,防止加载不必要的数据到内存中。
  2. 存在中间数据,且中间数据被重复使用时,应该使用IQueryable.ToList()立即加载到内存里使用(都被重复使用了,应该叫做最终数据了吧..);
  3. 如果中间结果无用,且想对IQueryable对象使用Func(C#语法)的扩展方法,应该使用IQueryable.AsEnumerable()转成IEnumerable对象,进行后续操作。

参考

  1. LINQ查询中的IEnumerable<T>和IQueryable<T>
  2. LINQ使用细节之.AsEnumerable()和.ToList()的区别
  3. 建议29:区别LINQ查询中的IEnumerabl<T>和IQueryable<T> - 陆敏技《编写高质量代码改善C#程序的157个建议》

原文地址:https://www.cnblogs.com/doThing/p/9942841.html

时间: 2024-10-02 15:48:14

IQueryable和IEnumerable以及AsEnumerable()和ToList()的区别的相关文章

LINQ使用细节之.AsEnumerable()和.ToList()的区别

原文http://www.cnblogs.com/Mainz/archive/2011/04/08/2009485.html 先看看下面的代码,用了 .AsEnumerable(): var query = (from a in db.Table where a = SomeCondition select a.SomeNumber).AsEnumerable(); int recordCount = query.Count(); int totalSomeNumber = query.Sum(

.AsEnumerable() 和 .ToList() 的区别:

.AsEnumerable()延迟执行,不会立即执行.当你调用.AsEnumerable()的时候,实际上什么都没有发生. .ToList()立即执行 当你需要操作结果的时候,用.ToList(),否则,如果仅仅是用来查询不需要进一步使用结果集,并可以延迟执行,就用.AsEnumerable()/IEnumerable /IQueryable .AsEnumerable()虽然延迟执行,但还是访问数据库,而.ToList()直接取得结果放在内存中.比如我们需要显示两个部门的员工时,部门可以先取出

C# IQueryable和IEnumerable的区别

原文地址:http://blog.csdn.net/q646926099/article/details/52297897 在使用EF查询数据的时候,我们常用的查询数据方式有linq to sql,linq to object, 查询返回的结果有两种类型:IQueryable.IEnumerable,两者内部的处理机制是完全不同的. 清楚认识,这里也是一个数据查询的优化点. 在System.linq命名空间,有两个静态类:Queryable和Enumerable. 在System.linq.Qu

IQueryable 和 IEnumerable(二)

IQueryable 和 IEnumerable的扩展方法 一  我们从ef的DbSet<T>看起来,我们看到他继承了IQueryable<T> 和 IEnumerable<T> 二 写了个例子,分别传入Expression<Func<T,bool>>和Func<T,bool> static void Main(string[] args) { Test<Users> ut = new Test<Users>(

linq中AsEnumerable和AsQueryable的区别

本文导读:用Linq来操作集合的时候会用到AsQueryable()和AsEnumerable(),何时该用AsQueryable()和何时该用AsEnumerable(),或许存在些疑惑.AsQueryable是在数据库中查询再返回数据,AsEnumerable是从数据库读取全部数据再在程序中查询. 在使用LINQ 进行数据集操作时,LINQ 不能直接从数据集对象中查询,因为数据集对象不支持LINQ 查询,所以需要使用AsEnumerable 方法返回一个泛型的对象以支持LINQ 的查询操作.

LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别【转】

在写LINQ语句的时候,往往会看到.AsEnumerable() 和 .AsQueryable() .例如: string strcon ="Data Source=.\\SQLEXPRESS;Initial Catalog=Db_Example;Persist Security Info=True;User ID=sa;Password=sa";SqlConnection con =new SqlConnection(strcon);con.Open();string strsql

IEnumerable,ICollection,IList,List之间的区别【转】

做C#的同学们,都知道,一类只能有一个继承类,但可以实现多个接口.这句话就告诉我们:IEnumerable,ICollection,IList,List区别了 首先我看看 IEnumerable: // 摘要: // 公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代. // // 类型参数: // T: // 要枚举的对象的类型. [TypeDependency("System.SZArrayHelper")] public interface IEnumerable<ou

关于IQueryable和IEnumerable

园里对这两个已经有很多文章作了深入的介绍,我总结些,当成笔记用. 一.具体判断用哪个上,如果是运行在本地内存中的,用IEnumerable,枚举该对象时,会立即反应查询结果. 如果是远程数据源,比如数据库,为优化查询,减少中间环节,要把多条语句先存放到表达式数里,等执行ToList方法时才会去真正调用迭代器GetEnumerator()取值,会去执行IQueryProvider中的Excute方法.得到最终结果,就是延时加载. 二.个人认为在不确认哪个更适用的情况下用IQueryable,因为从

LINQ语句中的.AsEnumerable() 和 .AsQueryable()的区别

在写LINQ语句的时候,往往会看到.AsEnumerable() 和 .AsQueryable() . 上述代码使用LINQ 针对数据集中的数据进行筛选和整理,同样能够以一种面向对象的思想进行数据集中数据的筛选.在使用LINQ 进行数据集操作时,LINQ 不能直接从数据集对象中查询,因为数据集对象不支持LINQ 查询,所以需要使用AsEnumerable 方法返回一个泛型的对象以支持LINQ 的查询操作. .AsEnumerable()是延迟执行的,实际上什么都没有发生,当真正使用对象的时候(例