LINQ其實很簡單

會寫這一篇是有原因的,不只一次有人問我,要不要學LINQ呢?
LINQ看起來很難耶...為何要放棄以前的SQL來學LINQ呢?到底LINQ的意義是什麼?

反正就是有一缸子的問題,說真的,由於最近也沒時間寫本LINQ的書,但是工作累了順手寫寫BLOG還可以,所已針對LINQ這個主題,和大家有一些分享。

其實對於VB開發人員來說,掌握LINQ說真的比C#來的簡單很多,主要的原因就是VB當中有非常多"自動"的隱含型別轉換,是不需要寫程式碼的,也因此操作起來比起C#真的容易不少。

要掌握LINQ的精神,得要知道LINQ出現的目的,其實很簡單,只有一句話,就是希望 "能夠達成以單一的一種語法來查詢多種不同的對象" 的目的。這其來有自,過去我們要查詢資料庫要用SQL、要查詢XML要用XMLDOM物件、要查詢AD又要用另一種不同的查詢方式,總之,查詢這個動作一天到晚出現在電腦程式碼當中,但是開發人員卻要學習多種不同的方式,很困擾,所以LINQ就出現了。

所謂的LINQ,是 .NET Language Integrated Query,也就是在.NET的開發語言當中,直接把查詢的技術給 "整" 進去,目的就是要加快搜尋(速度)與降低開發成本。

所以從.NET 3.5開始, LINQ變成.NET標準語法的一部分,OK,就是這樣,所以我們來看看 LINQ怎麼查詢,首先,為了展示LINQ,我定義了底下這樣的結構:

Structure BMI
  Dim name As String
  Dim height As Integer
  Dim weight As Integer
  Dim BmiValue As Single
End Structure

你用類別也可以,總之上面的結構用來表達一個人的身高,體重,名稱和BMI值。

接著,我撰寫底下程式碼:

'定義陣列
Dim matrix(5) As BMI
'填入測試資料
matrix(0).name = "王小寶"
matrix(0).height = 170
matrix(0).weight = 65
matrix(1).name = "韋大寶"
matrix(1).height = 176
matrix(1).weight = 95
matrix(2).name = "章新寶"
matrix(2).height = 150
matrix(2).weight = 55
matrix(3).name = "沈中寶"
matrix(3).height = 192
matrix(3).weight = 75
matrix(4).name = "蕭敦寶"
matrix(4).height = 150
matrix(4).weight = 65
matrix(5).name = "林寶寶"
matrix(5).height = 177
matrix(5).weight = 75

上面這段程式碼就只是很簡單的把資料填入,請注意我們只填入身高體重和姓名,接著,再利用底下的程式碼算出BMI:

'計算BMI
For i = 0 To 5
  matrix(i).BmiValue = matrix(i).weight / (matrix(i).height / 100) ^ 2
Next

OK,到這邊先告一個段落,以上都沒有LINQ出現,動作也很簡單,接下來換LINQ出場,在出場前先問讀者一個問題,如果要找出BMI值>25的資料,你會怎麼寫程式?

...

沒錯,用for each指令,在沒有LINQ功能的時代,我們只能用陣列巡覽的方式查找每一個元素,找出符合的資料,但是有底下幾個問題:
1.為了找出特定的資料而跑整個陣列,看起來挺蠢的。(不過說真的,如果資料沒有排序,也就只能那麼蠢)
2.可能有一些初學的菜鳥程式設計師,寫出效率很差的查找程式。(例如不小心在for each當中做了一些不必要的動作)

OK,過去我們對於物件(或是物件陣列)的操作,也就只能使用迴圈的方式,但是LINQ提出了一種新的可能,就是透過類似SQL的查找語法,讓開發人員可以用簡單的程式碼,就可以針對物件進行複雜的查詢。(更重要的是,未來這種簡單的查找語法變成主流之後,可以用以查詢"各種不同的對象",而不只有查找"物件")

言歸正傳,若要查找出BMI值>25的資料,你可以透過底下的LINQ程式:

'查詢BMI值大於25的人
Dim result = From c In matrix Where c.BmiValue > 25

結束,就是這樣,而 result 就是找出的結果物件,你可以透過 result 來取得每一個符合條件的資料。簡單的說,上面這段程式碼的意思是,從matrix物件集合當中,找出一些資料,這些資料的BmiValue屬性大於25。其中的 c 只是撰寫程式碼方便,c代表該物件元素,你也可以用別的字眼..

而找出的資料result也是一個集合,你可以透過底下的程式碼來列出每一個BMI值符合條件者的名字:

'顯示名稱
For Each item In result
  MsgBox(item.name)
Next

很簡單不是嗎? result 當中的每一個 item ,其型別就是 BMI,因為Result物件是LINQ語法跑出的結果,所以只有包含符合 BmiValue > 25 這個條件的人...

上面這段程式碼,還可以這樣寫...

'顯示名稱
For Each item In (From c In result Select c.name)
  MsgBox(item)
Next

效果完全一樣唷,但是,(From c In result Select c.name) 會產生一個物件,該物件只有符合條件者的名稱(相當於一維陣列),而item的型別當然就是string。

透過上面這樣的指令,查找動作變得相當簡單,還不僅如此,關鍵在於底下這樣的語法:

'查詢BMI值大於25的人
Dim result = From c In matrix Where c.BmiValue > 25

具有相當多不同的變化方式,可以組合出各種不同的形式,發揮出強大的查找力量,再加上學一次,就可以用在各種不同的地方(這邊我們只用來查找物件,其實也可以查找XML和Database),使得LINQ的用途更加的廣泛,這就是LINQ的價值與意義。

以後,再跟大家分享一些關於LINQ的其他部分,希望對大家有幫助,VB developer其實是幸福的,LINQ其實是很簡單的...

留言

匿名表示…
謝謝老師,茅塞頓開啦~
匿名表示…
老師會再繼續介紹一些 LINQ 的應用嗎?
匿名表示…
LINQ畢竟只在.NET 3.5支援,老師建議我們在程式碼當中,開始使用LINQ嗎?還是過一兩年等到.NET 4.0再說?
David寫道…
會的LINQ的部分應該會整理幾篇文章出來,何時開始用?現在囉~
Unknown寫道…
真的很謝謝您的解說><
翻書一直不懂LINQ的意思到底是甚麼,可是經過您一說,整個都明朗了!!真的很謝謝!!
TACO寫道…
請教前輩
直接練習那個範例的時候,會出現下列錯誤訊息
-->型別'1-維陣列屬於Default6.Weight'的運算式無法查詢,請確定您有沒有遺漏組件參考及(或)LINQ提供者的命名空間匯入。

(卡在Dim result = From c In matrix Where c.BmiValue > 25這一行)

且 For Each item In result
MsgBox(item.name)
Next
它會說item還沒有宣告,
煩請前輩指點
謝謝
匿名表示…
謝謝分享!! 終於了解LinQ 的用法

這個網誌中的熱門文章

原來使用 .net 寫個 MCP Server 如此簡單

使用LM Studio輕鬆在本地端以API呼叫大語言模型(LLM)

開啟 teams 中的『會議轉錄(謄寫)』與Copilot會議記錄、摘要功能

原來使用 .net 寫個 MCP Client 也如此簡單

使用 Dify 建立企業請假機器人