1. 程式人生 > >IQueryable、IEnumberable 、IList與List區別

IQueryable、IEnumberable 、IList與List區別

接口 ble 基於 持久 功能 泛型接口 div 泛型類 查詢


基本概念:

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>接口規定的功能而已



使用:
//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>

IQueryable、IEnumberable 、IList與List區別