国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Linq之延遲加載特性

2019-11-17 02:35:00
字體:
來源:轉載
供稿:網友

Linq之延遲加載特性

目錄

寫在前面

系列文章

延遲加載

總結

寫在前面

上篇文章介紹了linq中常見的幾個關鍵字,并列舉了幾個例子,算是對linq如何使用有了初步了解。上篇文章中也提到了,能夠使用linq的場合有一個要求:實現IEnumerable<T>泛型接口,或者類型兼容(可以通過Cast方法轉換,比如ArrayList)。

系列文章

Linq之Lambda表達式初步認識

Linq之Lambda進階

Linq之隱式類型、自動屬性、初始化器、匿名類

Linq之擴展方法

Linq之ExPRession初見

Linq之Expression進階

Linq之Expression高級篇(常用表達式類型)

Linq之常見關鍵字

延遲加載

延遲加載在很多orm框架中都有支持,什么是延遲加載?通俗一點,就是你需要的時候再去查詢,不需要的時候就不查詢。

Linq查詢的執行結果是IEnumerable<T>類型,而對IEnumerable<T>,在內部,C#通過yield關鍵字實現迭代器達到延遲加載的目的。從而使Linq查詢只是在需要的時候才會被執行。

下面看一個例子

 1 namespace Wolfy.LinqLazyLoad 2 { 3     class Program 4     { 5         static void Main(string[] args) 6         { 7             List<Person> persons = new List<Person>() {  8             new Person(){ ID=1,Name="wolfy1", Age=1}, 9              new Person(){ ID=2,Name="wolfy2", Age=2},10               new Person(){ ID=3,Name="wolfy3", Age=3},11                new Person(){ ID=4,Name="wolfy4", Age=4},12                 new Person(){ ID=5,Name="wolfy5", Age=5},13                  new Person(){ ID=6,Name="wolfy6", Age=6}14             };15             //這里使用linq進行查詢16             var query = from p in persons17                         .OrderByDescending(p => p.Age)18                         select new { p.ID, p.Name, p.Age };19             //如果是linq是延遲加載的,則輸出的結果就應該是修改后的(延遲加載,說明query中此時并沒有實際加載數據)20             //如果linq立即加載的,則此時query中就相當于一個臨時的緩沖區,數據已經存在了query中,就算對persons中某一項修改并不影響query中的數據。21             persons[2] = new Person() { ID = 7, Name = "zhangsan", Age = 7 };22             foreach (var item in query)23             {24                 Console.WriteLine(item.ToString());25             }26             Console.Read();27         }28     }29     class Person30     {31         public int ID { set; get; }32         public string Name { set; get; }33         public int Age { set; get; }34         public override string ToString()35         {36             return ID + " " + Name + " " + Age;37         }38     }39 }

例子很簡單,通過linq查詢,按年齡降序輸出。

看一下輸出結果

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

那么我們再舉一個linq立即加載的例子,對比一下

 1   static void Main(string[] args) 2         { 3             List<Person> persons = new List<Person>() {  4             new Person(){ ID=1,Name="wolfy1", Age=1}, 5              new Person(){ ID=2,Name="wolfy2", Age=2}, 6               new Person(){ ID=3,Name="wolfy3", Age=3}, 7                new Person(){ ID=4,Name="wolfy4", Age=4}, 8                 new Person(){ ID=5,Name="wolfy5", Age=5}, 9                  new Person(){ ID=6,Name="wolfy6", Age=6}10             };11             //使用聚合函數年齡總和12             var result = (from p in persons13                          select p.Age)14                         .Sum();15             //如果是linq是延遲加載的,則輸出的結果就應該是修改后的(延遲加載,說明query中此時并沒有實際加載數據)16             //如果linq立即加載的,則此時query中就相當于一個臨時的緩沖區,數據已經存在了query中,就算對persons中某一項修改并不影響query中的數據。17             persons[2] = new Person() { ID = 7, Name = "zhangsan", Age = 7 };18             Console.WriteLine("Sum " + result);19             Console.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<T>類型,而對IEnumerable<T>,在內部,C#通過yield關鍵字實現迭代器達到延遲加載的目的。從而使Linq查詢只是在需要的時候才會被執行,可以得到這樣的結論:

1、可以自定義一個類實現泛型接口IEnumerable<T>,在迭代器塊中通過yield關鍵字,可以實現延遲加載的目的。

2、linq中使用聚合函數,將會強制查詢,將強制進行立即加載。

上面的例子,有點繞,各種緣由,需慢慢體會。

思考:為什么yield關鍵字就能實現延遲加載的特性呢?(查找很多資料,未果)

參考文章

http://kb.VEVb.com/page/100043/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 渭源县| 天气| 康定县| 蒙山县| 吴堡县| 吉隆县| 江津市| 江都市| 含山县| 运城市| 和平县| 澄城县| 灵寿县| 南汇区| 获嘉县| 济宁市| 奉化市| 甘南县| 赤城县| 札达县| 项城市| 灵丘县| 金川县| 临城县| 临邑县| 会泽县| 安吉县| 大英县| 古交市| 攀枝花市| 平潭县| 松原市| 阿鲁科尔沁旗| 阆中市| 神农架林区| 靖远县| 靖安县| 共和县| 祁门县| 资源县| 仲巴县|