LINQ全稱是「Language-Integrated Query」。如果你想要使用或學習LINQ,那你必須安裝.NET Framework 3.5以上,才有辦法使用。
在使用LINQ時有一地方需要特別小心,就是LINQ在「反應」的時間點。LINQ本身預設為「延遲查詢」。什麼是延遲查詢?我這樣說好了,我們寫程式,預設是從上到下,從右到左執行,也就是執行一行就有一行的效果,例如:「
Dim intStu = New Integer() {...} 」當complier執行到這一行,這一行中的
intStu馬上就產生為數值陣列,這樣的執行模式稱「立即執行」。
但延遲查詢剛好相反,也就是說,就算complier已經執行過這一段程式,
但在沒有其他程式使用到之前,它不會產生任何效果。
以下我們來看實際的例子,Default.asp中Page_Load事件:
'Implicit
Dim intStu = New Integer() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
'LINQ,選擇「偶數」
Dim even = From n In intStu Where n Mod 2 = 0 Select n
Response.Write("LINQ 第一次:<br />")
For Each n In even
Response.Write(n & "<br />")
Next
'改變陣列值
intStu(0) = 200
Response.Write("LINQ 第二次:<br />")
For Each n In even
Response.Write(n & "<br />")
Next
執行後的結果會如下:
LINQ 第一次:
2
4
6
8
10
LINQ 第二次:
200 '這裡是重點
2
4
6
8
10
請注意第二次中的第一個結果。我們在執行完LINQ後,程式並沒有馬上產生作用,而是等到有人使用時(
For Each n In even),才會去執行。所以在我把陣列的值(
intStu(0))做改變後,再去執行第二次的For Each語法時,第二次的For Each會去
觸發第二次的LINQ查詢,而LINQ再去讀取已經被修改過的陣列,所以造成第二次第一筆值為
200。
那如果我今天是希望LINQ查詢的結果是固定的,也就是說,不管我事後如何修改陣列值,事後的For Each結果都是一樣的,那你就必須讓LINQ查詢當下要立即執行。立即執行LINQ也很簡單,可以使用
ToArray()或
ToList()方法來強制立即執行。
'LINQ,選擇「偶數」
'使用ToArray或ToList讓LINQ立即執行
'Dim even = (From n In intStu Where n Mod 2 = 0 Select n).ToList
Dim even = (From n In intStu Where n Mod 2 = 0 Select n).ToArray
執行結果,你會看到第一次與第二次完全一模一樣,第二次不再受陣列改變的影響,也就是說,使用使用ToArray或ToList方法後,LINQ語法已經立即產生作用,而第一次與第二次For Each只是將
even變數值
讀出,而不是去觸發LINQ查詢。
這一點差異是我們在使用LINQ時要小心的地方,不然程式怎麼看都對,邏輯上下右左也查不出所以然,為什麼執行出來的結果永遠不是我們想要的,記得「
LINQ預設是延遲執行」。