寫在前面
系列文章
延遲載入
總結上篇文章介紹了linq中常見的幾個關鍵字,並列舉了幾個例子,算是對linq如何使用有了初步了解。上篇文章中也提到了,能夠使用linq的場合有乙個要求:實現ienumerable泛型介面,或者型別相容(可以通過cast方法轉換,比如arraylist)。
linq之lambda表示式初步認識
linq之lambda高階
linq之隱式型別、自動屬性、初始化器、匿名類
linq之擴充套件方法
linq之expression初見
linq之expression高階
linq之expression高階篇(常用表示式型別)
linq之常見關鍵字
延遲載入在很多orm框架中都有支援,什麼是延遲載入?通俗一點,就是你需要的時候再去查詢,不需要的時候就不查詢。
linq查詢的執行結果是ienumerable型別,而對ienumerable,在內部,c#通過yield關鍵字實現迭代器達到延遲載入的目的。從而使linq查詢只是在需要的時候才會被執行。下面看乙個例子
1例子很簡單,通過linq查詢,按年齡降序輸出。namespace
wolfy.linqlazyload2,
9new person(),
10new person(),
11new person(),
12new person(),
13new person()
14};
15//
這裡使用linq進行查詢
16var query = from p in
persons
17 .orderbydescending(p =>p.age)
18select
new;
19//
如果是linq是延遲載入的,則輸出的結果就應該是修改後的(延遲載入,說明query中此時並沒有實際載入資料)
20//
如果linq立即載入的,則此時query中就相當於乙個臨時的緩衝區,資料已經存在了query中,就算對persons中某一項修改並不影響query中的資料。
21 persons[2] = new person() ;
22foreach (var item in
query)
2326
console.read();27}
28}29class
person
3032
public
string name
33public
int age
34public
override
string
tostring()
3538
}39 }
看一下輸出結果
通過這點也許你可能還不是很清楚。
那麼我們再舉乙個linq立即載入的例子,對比一下
1輸出結果static
void main(string
args)2,
5new person(),
6new person(),
7new person(),
8new person(),
9new person()
10};
11//
使用聚合函式年齡總和
12var result = (from p in
persons
13select
p.age)
14.sum();
15//
如果是linq是延遲載入的,則輸出的結果就應該是修改後的(延遲載入,說明query中此時並沒有實際載入資料)
16//
如果linq立即載入的,則此時query中就相當於乙個臨時的緩衝區,資料已經存在了query中,就算對persons中某一項修改並不影響query中的資料。
17 persons[2] = new person() ;
18 console.writeline("
sum
" +result);
19console.read();
20 }
21=1+2+3+4+5+6。這裡也說明乙個問題,在linq中,一些聚合函式例如sum,求平均值等操作會影響linq的延遲載入特性。
上面的第乙個例子是延遲載入,在query中並沒有載入資料,然後你修改了persons[2]的值,你再輸出query中的每乙個值的時候,此時才是真正的載入資料,而此時載入資料,persons[2]的值已經發生變化了,所以會輸出最新的persons[2]。
第二個例子中,聚合函式為什麼會影響延遲載入特性呢,其實也很好理解,比如在該例子中進行求和運算,求和運算就需要所有的值,所以就需要先將值查詢出來,然後才能求和,此時已經將結果儲存在了result中,就算你下面再修改persons[2]的值,也沒有用了。
通過上面的例子,以及linq查詢的執行結果是ienumerable型別,而對ienumerable,在內部,c#通過yield關鍵字實現迭代器達到延遲載入的目的。從而使linq查詢只是在需要的時候才會被執行,可以得到這樣的結論:
1、可以自定義乙個類實現泛型介面ienumerable,在迭代器塊中通過yield關鍵字,可以實現延遲載入的目的。
2、linq中使用聚合函式,將會強制查詢,將強制進行立即載入。
上面的例子,有點繞,各種緣由,需慢慢體會。
思考:為什麼yield關鍵字就能實現延遲載入的特性呢?(查詢很多資料,未果)
參考文章
部落格版權:
Linq之延遲載入特性
寫在前面 系列文章 延遲載入 總結上篇文章介紹了linq中常見的幾個關鍵字,並列舉了幾個例子,算是對linq如何使用有了初步了解。上篇文章中也提到了,能夠使用linq的場合有乙個要求 實現ienumerable泛型介面,或者型別相容 可以通過cast方法轉換,比如arraylist linq之lam...
Linq的延遲載入問題
什麼是延遲載入 所謂延遲載入就是當在真正需要資料的時候,才真正執行資料載入操作。可以簡單理解為,只有在使用的時候,才會發出sql語句進行查詢,資料是分n次讀取。classinfo表 stuinfo表 2個表的關係就不要我多說了 一 接下來看延遲載入 linqdbdatacontext db new ...
LINQ中的 延遲查詢 特性
很多標準查詢操作符的設計原型都是返回乙個ienumerable型別的序列,這些標準查詢操作實際上不會在 執行到那一行的時候就返回乙個序列,事實上返回的是乙個物件.當在列舉 比如foreach 這個物件的時候會從ienumerable序列中生成乙個元素,這個時候才會真正執行查詢操作.這就是所謂的 延遲...