日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用

發布時間:2024/4/15 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

延遲執行的經典例子

我們用?select ++i 就可以看到在foreach 時候,查詢才被執行。

public static void Linq99()
{
??? int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
??? int i = 0;
??? var q = from n in numbers select ++i;
??? foreach (var v in q)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
}

輸出結果:

v = 1, i = 1
v = 2, i = 2
v = 3, i = 3
v = 4, i = 4
v = 5, i = 5
v = 6, i = 6
v = 7, i = 7
v = 8, i = 8
v = 9, i = 9
v = 10, i = 10

foreach每一個遍歷的時候,select出來的值和當前i的值都是一樣的。

?

立即執行的經典例子:

public static void Linq99()
{
??? int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
??? int i = 0;
??? var q = (from n in numbers select ++i).ToList();
??? foreach (var v in q)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
}

執行結果:

v = 1, i = 10
v = 2, i = 10
v = 3, i = 10
v = 4, i = 10
v = 5, i = 10
v = 6, i = 10
v = 7, i = 10
v = 8, i = 10
v = 9, i = 10
v = 10, i = 10

這個例子的代碼跟上面延遲執行的例子代碼唯一的差別在于多了一個.ToList();
這也可以證明我們之前提到的原則:

只有到用的時候才會去執行查詢

由于 .ToList(); 的存在,在這里就要用到了,所以在這里就執行了查詢,而不是在foreach中執行查詢。注意,這時候出來的結果是一個數組了.參看后面的幾個例子.

執行的一個特殊情況:重復執行

請看下面例子:

查詢出一個int數組中小于3的數字。

下面例子中在第一次查詢后,對數據源作了修改,然后再作第二次查詢,我們可以看到第二次我們不需要再作

lowNumbers = from n in numbers where n <= 3 select n; 這樣的定義,而是直接使用??? foreach (int n in lowNumbers)。另外這兩次的返回結果是不同的,因為我們
在第一次查詢后,對數據源作了修改。

public static void Linq101()
{
??? int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
??? var lowNumbers = from n in numbers where n <= 3 select n;
??? Console.WriteLine(“First run numbers <= 3:”);
??? foreach (int n in lowNumbers)
??????? Console.WriteLine(n);

??? for (int i = 0; i < 10; i++)
??????? numbers[i] = -numbers[i];

??? Console.WriteLine(“Second run numbers <= 3:”);
??? foreach (int n in lowNumbers)
??????? Console.WriteLine(n);
}

輸出結果:

First run numbers <= 3:
1
3
2
0
Second run numbers <= 3:
-5
-4
-1
-3
-9
-8
-6
-7
-2
0

以上三個例子均來自 101 LINQ Samples

?

下面我們再來看幾個例子,加深對查詢執行的理解:

重復查詢的再一個例子:

public static void Linq102()
{
??? int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
??? int i = 0;
??? var q = from n in numbers select ++i;
??? foreach (var v in q)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
??? foreach (var v in q)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
}

執行結果:

v = 1, i = 1
v = 2, i = 2
v = 3, i = 3
v = 4, i = 4
v = 5, i = 5
v = 6, i = 6
v = 7, i = 7
v = 8, i = 8
v = 9, i = 9
v = 10, i = 10
v = 11, i = 11
v = 12, i = 12
v = 13, i = 13
v = 14, i = 14
v = 15, i = 15
v = 16, i = 16
v = 17, i = 17
v = 18, i = 18
v = 19, i = 19
v = 20, i = 20

?

只執行一次的立即查詢:

public static void Linq102()
{
??? int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
??? int i = 0;
??? var q = (from n in numbers select ++i).ToList();
??? foreach (var v in q)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
??? foreach (var v in q)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
}

執行結果:

v = 1, i = 10
v = 2, i = 10
v = 3, i = 10
v = 4, i = 10
v = 5, i = 10
v = 6, i = 10
v = 7, i = 10
v = 8, i = 10
v = 9, i = 10
v = 10, i = 10
v = 1, i = 10
v = 2, i = 10
v = 3, i = 10
v = 4, i = 10
v = 5, i = 10
v = 6, i = 10
v = 7, i = 10
v = 8, i = 10
v = 9, i = 10
v = 10, i = 10

那些函數會導致立即執行查詢:

以下幾個擴展函數會導致LINQ會立即執行。并且只執行一次。

.ToArray();

.ToList();

.ToDictionary(k => k);

比如:

public static void Linq102()
{
??? int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
??? int i = 0;
??? var q = (from n in numbers select ++i).ToDictionary(k => k);
??? foreach (var v in q)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
??? foreach (var v in q)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
}

輸出結果就是:

v = [1, 1], i = 10
v = [2, 2], i = 10
v = [3, 3], i = 10
v = [4, 4], i = 10
v = [5, 5], i = 10
v = [6, 6], i = 10
v = [7, 7], i = 10
v = [8, 8], i = 10
v = [9, 9], i = 10
v = [10, 10], i = 10
v = [1, 1], i = 10
v = [2, 2], i = 10
v = [3, 3], i = 10
v = [4, 4], i = 10
v = [5, 5], i = 10
v = [6, 6], i = 10
v = [7, 7], i = 10
v = [8, 8], i = 10
v = [9, 9], i = 10
v = [10, 10], i = 10

?

小結:

Q:通過上面幾個例子,我們該如何理解LINQ的查詢何時執行呢?

A:LINQ的查詢執行遵循以下原則:

1、一般情況下(除了下面第三條說的情況),LINQ都是延遲執行,原因:以DLINQ為例,越晚被執行,對業務邏輯的理解就越清晰,DLINQ查詢對數據庫的請求壓力越小。編譯器對LINQ查詢優化可作的事情越多。

2、由于是延遲執行,也就是調用的時候才去執行。這樣調用一次就被執行一次,這樣就具備了重復執行的功能,參看之前的幾個重復執行的例子。而這個重復執行是不需要再此書寫一邊查詢語句的。

3、如果查詢中我們對查詢結果使用了 ToArray、ToList、ToDictionary 這些轉換成集合的擴展方法。使用這時候出來的對象是一個獨立的集合數組,而不是LINQ查詢,所以這時候不會出現多次查詢,而只是一次查詢。

即:var q = from n in numbers select ++i ;? 這樣一條語句我們可以認為它記錄的不是等號右邊的結果,而是記錄的等號右邊的表達式。

而??? var q = (from n in numbers select ++i).ToDictionary(k => k); 這樣一條語句我們記錄的是等號右邊的計算結果,而不是表達式。

為理解上面說明,我們可以再看兩個例子:

public static void Linq102()
{
??? int[] numbers = new int[] { 5,
4, 1, 3, 9, 8, 6, 7, 2, 0 };
??? int i = 0;
??? var q = from n in numbers select ++i;
??? var qq = q.ToDictionary(k => k);
??? foreach (var v in q)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
??? foreach (var v in q)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
}

輸出結果:

v = 11, i = 11
v = 12, i = 12
v = 13, i = 13
v = 14, i = 14
v = 15, i = 15
v = 16, i = 16
v = 17, i = 17
v = 18, i = 18
v = 19, i = 19
v = 20, i = 20
v = 21, i = 21
v = 22, i = 22
v = 23, i = 23
v = 24, i = 24
v = 25, i = 25
v = 26, i = 26
v = 27, i = 27
v = 28, i = 28
v = 29, i = 29
v = 30, i = 30

public static void Linq102()
{
??? int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
??? int i = 0;
??? var q = from n in numbers select ++i;
??? var qq = q.ToDictionary(k => k);
??? foreach (var v in qq)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
??? foreach (var v in qq)
??????? Console.WriteLine(“v = {0}, i = {1}”, v, i);
}

輸出結果為:

v = [1, 1], i = 10
v = [2, 2], i = 10
v = [3, 3], i = 10
v = [4, 4], i = 10
v = [5, 5], i = 10
v = [6, 6], i = 10
v = [7, 7], i = 10
v = [8, 8], i = 10
v = [9, 9], i = 10
v = [10, 10], i = 10
v = [1, 1], i = 10
v = [2, 2], i = 10
v = [3, 3], i = 10
v = [4, 4], i = 10
v = [5, 5], i = 10
v = [6, 6], i = 10
v = [7, 7], i = 10
v = [8, 8], i = 10
v = [9, 9], i = 10
v = [10, 10], i = 10

?

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的LINQ 的查询执行何时是延迟执行,何时是立即执行,以及查询的复用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。