1. 程式人生 > >大話 IQueryable和IEnumberable and IList與Lis t區別

大話 IQueryable和IEnumberable and IList與Lis t區別

雖然一直在使用,卻對其概念和原理不作深入瞭解,特地查閱了資料寫原始碼做了測試,本人能力有限,部分講解有錯的望留言糾正.

基本概念:

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/wisdo/p/4984870.html  thx.