IQueryable、IEnumberable 、IList与List区别

虽然一直在使用,却对其概念和原理不作深入了解,特地查阅了资料写源码做了测试,本人能力有限,部分讲解有错的望留言纠正.

基本概念:

IEnumerable:使用的是LINQ to Object方式,它会将AsEnumerable()时对应的所有记录都先加载到内存,然后在此基础上再执行后来的Query

IQeurable(IQuerable<T>):不在内存加载持久数据,因为这家伙只是在组装SQL,(延迟执行) 到你要使用的时候,例如 list.Tolist() or list.Count()的时候,数据才从数据库进行加载 (AsQueryable())。

IList(IList<T>):泛型接口是 ICollection 泛型接口的子代,作为所有泛型列表的基接口,在用途方面如果作为数据集合的载体这是莫有问题的,只是如果需要对集合做各种的操作,例如 排序 编辑 统计等等,它不行。

List <> :泛型类,它已经实现了IList <> 定义的那些方法,IList<T> list=new List<T>();只是想创建一个基于接口IList<Class1>的对象的实例,这个接口是由List<T>实现的。只是希望使用到IList<T>接口规定的功能而已

抽象场景:
其实在我们之前没有使用 ORM 的的很久很久以前,我们 在ADO.net 里面使用的 DataReader 和 DataAdapter or DataSet 和这几个货的基本原理都接近的,就是读取数据的时候,一个必须独占着数据库的连接,而另一个就是先把数据库的的局加载到了自己本地,然后再进行操作。
举个简单的例子就是: 一般的火锅都有专门的调料桌,像我我喜欢芝麻酱,我就拿了一个,回来就开刷了,B君比较大条,不管喜不喜欢拿了十几种调料过来,而C君比较理性,他把自己不喜欢的都排除了,然后一个个针对性的拿过来。

使用场景模拟:

//IList
IList users = res.ToList(); //此时已把users加载到内存,而每个user的关联实体(UserInfos)未
                                       //被加载,所以下一行代码无法顺利通过
var ss = users.Where(p => p.UserInfos.ID != 3); //此处报错,因为P的UserInfos实体无法被加载
 
// IQuerable的
IQueryable users = res.AsQueryable(); //users未被立即加载,关联实体可通过“延迟加载”获
                                   //得
var ss = users.Where(p => p.UserInfos.ID != 3);//此处顺利获得对应的ss
 

总结:

基于性能和数据一致性这两点,使用IQueryable时必须谨慎,而在大多数情况下我们应使用IList。

1.当你打算马上使用查询后的结果(比如循环作逻辑处理或者填充到一个table/grid中),并且你不介意该查询即时被执行后的结果可以供调用者(Consummer)作后续查询(比如这是一个"GetAll"的方法),或者你希望该查执行,使用ToList()
2.当你希望查询后的结果可以供调用者(Consummer)作后续查询(比如这是一个"GetAll"的方法),或者你希望该查询延时执行,使用AsQueryable()
3.按照功能由低到高:List<T> IList<T> IQueryable<T> IEnumerable<T>
4.按照性能由低到高:IEnumerable<T> IQueryable<T> IList<T> List<T>

总结内容借鉴:http://www.cnblogs.com/QingLang-Raymond/articles/5512377.html

posted on 2017-12-27 10:25  张军伟  阅读(290)  评论(0编辑  收藏  举报

导航