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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM