Linq之延遲載入特性

2021-09-06 21:08:52 字數 3072 閱讀 5699

寫在前面

系列文章

延遲載入

總結上篇文章介紹了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

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查詢,按年齡降序輸出。

看一下輸出結果

通過這點也許你可能還不是很清楚。

那麼我們再舉乙個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序列中生成乙個元素,這個時候才會真正執行查詢操作.這就是所謂的 延遲...