Language-Integrated 查詢名稱 (LINQ) 指的是 Visual Basic 中的一種技術,支援直接在語言中使用的查詢語法和其他語言構造。 使用 LINQ 時,您不需要學習新的語言,即可針對外部數據源進行查詢。 您可以使用 Visual Basic 來查詢關係資料庫、XML 存放區或物件中的數據。 將查詢功能整合到語言中使其具備在編譯時檢查語法錯誤和類型安全性的能力。 這項整合也可確保您已經知道在 Visual Basic 中撰寫豐富、各種查詢所需的大部分內容。
下列各節將詳細說明支援LINQ的語言建構,讓您開始閱讀簡介檔、程式代碼範例和範例應用程式。 您也可以按下連結,以尋找語言功能如何結合在一起以啟用語言整合查詢的更詳細說明。 開始的好地方是 逐步解說:在 Visual Basic 中撰寫查詢。
查詢表達式
Visual Basic 中的查詢表達式可以用類似 SQL 或 XQuery 的宣告式語法來表示。 在編譯時期,查詢語法會轉換成對LINQ提供者實作標準查詢運算元擴充方法的方法呼叫。 應用程式會使用語句指定適當的命名空間 Imports ,來控制哪些標準查詢運算符在範圍內。 Visual Basic 查詢表達式的語法如下所示:
Dim londonCusts = From cust In customers
Where cust.City = "London"
Order By cust.Name Ascending
Select cust.Name, cust.Phone
如需詳細資訊,請參閱 Visual Basic 中的 LINQ 簡介。
隱式型別變數
您可以讓編譯程式推斷並指派類型,而不是在宣告和初始化變數時明確指定類型。 這稱為 局部類型推斷。
被推斷類型的變數是強類型別的,和您明確指定類型的變數一樣。 只有在您在方法主體內定義局部變數時,區域類型推斷才有效。 如需詳細資訊,請參閱 OptionInfer語句 和 本機類型推斷。
下列範例說明區域型別推斷。 若要使用此範例,您必須將 設定 Option Infer 為 On。
' The variable aNumber will be typed as an integer.
Dim aNumber = 5
' The variable aName will be typed as a String.
Dim aName = "Virginia"
本機類型推斷也可讓您建立匿名型別,本節稍後會說明此類型,而且對於LINQ查詢而言是必要的。
在下列 LINQ 範例中,如果 Option Infer 為 On 或 Off,就會發生類型推斷。 如果 Option Infer 是 Off,且 Option Strict 是 On,就會發生編譯時期錯誤。
' Query example.
' If numbers is a one-dimensional array of integers, num will be typed
' as an integer and numQuery will be typed as IEnumerable(Of Integer)--
' basically a collection of integers.
Dim numQuery = From num In numbers
Where num Mod 2 = 0
Select num
物件初始化表達式
當您必須建立匿名類型來保存查詢結果時,物件初始化表達式會用於查詢表達式中。 它們也可以用來初始化非查詢範圍中的具名類型物件。 藉由使用物件初始化表達式,您可以在單行中初始化物件,而不需明確呼叫建構函式。 假設您有一個名為Customer的類別,具備公開Name和Phone屬性,以及其他屬性,則可以以下列方式使用物件初始化運算式:
Dim aCust = New Customer With {.Name = "Mike",
.Phone = "555-0212"}
如需詳細資訊,請參閱 物件初始化表達式:具名和匿名類型。
匿名類型
匿名型別提供一個方便的方法,可以暫時將一組屬性分組成一個元素,以納入查詢結果中。 這可讓您依任何順序選擇查詢中可用欄位的任意組合,而不需定義專案的具名數據類型。
匿名類型是由編譯程式動態建構。 類型的名稱是由編譯程式指派,而且可能會隨著每個新的編譯而變更。 因此,無法直接使用名稱。 匿名類型會以下列方式初始化:
' Outside a query.
Dim product = New With {.Name = "paperclips", .Price = 1.29}
' Inside a query.
' You can use the existing member names of the selected fields, as was
' shown previously in the Query Expressions section of this topic.
Dim londonCusts1 = From cust In customers
Where cust.City = "London"
Select cust.Name, cust.Phone
' Or you can specify new names for the selected fields.
Dim londonCusts2 = From cust In customers
Where cust.City = "London"
Select CustomerName = cust.Name,
CustomerPhone = cust.Phone
如需詳細資訊,請參閱 匿名型別。
擴充方法
擴充方法可讓您從定義外部將方法新增至數據類型或介面。 這項功能可讓您實際將新方法新增至現有的類型,而不需要實際修改類型。 標準查詢運算符本身是一組擴充方法,可為實作 IEnumerable<T>的任何類型提供LINQ查詢功能。 其他的延伸模組包括IEnumerable<T>、Count、Union和Intersect。
下列擴充方法會將 print 方法新增至 String 類別。
' Import System.Runtime.CompilerServices to use the Extension attribute.
<Extension()>
Public Sub Print(ByVal str As String)
Console.WriteLine(str)
End Sub
呼叫 方法的方式就像是 的 String一般實例方法:
Dim greeting As String = "Hello"
greeting.Print()
如需詳細資訊,請參閱擴充方法。
Lambda 表達式
Lambda 運算式是沒有名稱的函式,可計算並傳回單一值。 不同於具名函式,Lambda 運算式可以同時定義和執行。 下列範例會顯示 4。
Console.WriteLine((Function(num As Integer) num + 1)(3))
您可以將 Lambda 運算式定義指派給變數名稱,然後使用名稱來呼叫函式。 下列範例也會顯示 4。
Dim add1 = Function(num As Integer) num + 1
Console.WriteLine(add1(3))
在 LINQ 中,Lambda 表達式的基礎是許多標準查詢運算符。 編譯程式會建立 Lambda 表達式,以擷取基本查詢方法中定義的計算,例如 Where、 Select、 Order By、 Take While等。
例如,下列程式代碼會定義從學生清單中傳回所有資深學生的查詢。
Dim seniorsQuery = From stdnt In students
Where stdnt.Year = "Senior"
Select stdnt
查詢定義會編譯成類似下列範例的程序代碼,它會使用兩個 Lambda 表達式來指定 和 Where的Select自變數。
Dim seniorsQuery2 = students.
Where(Function(st) st.Year = "Senior").
Select(Function(s) s)
任一 For Each 版本都可以使用循環來執行:
For Each senior In seniorsQuery
Console.WriteLine(senior.Last & ", " & senior.First)
Next
如需詳細資訊,請參閱 Lambda 運算式。