Visual Basic 中的 LINQ 簡介
Language-Integrated Query (LINQ) 將查詢功能加入 Visual Basic,在您使用所有類型的資料時,為您提供簡單而強大的功能。 LINQ 將查詢當成 Visual Basic 語言的一部分導入,而不是將查詢傳送至資料庫加以處理,或針對您搜尋的各種類型資料,使用不同的查詢語法。 它使用統一的語法,不論資料類型為何。
LINQ 可讓您從 SQL Server 資料庫、XML、記憶體內部的陣列和集合、ADO.NET 資料集,或任何支援 LINQ 的其他遠端或本機資料來源查詢資料。 使用一般的 Visual Basic 語言元素即可執行上述所有作業。 因為查詢是以 Visual Basic 語言撰寫而成,所以傳回的查詢結果會是強類型物件。 這些物件支援 IntelliSense,讓您加快撰寫程式碼的速度,並在編譯階段即捕捉查詢中的錯誤,而不是在執行階段。 LINQ 查詢可用做其他查詢來源,以精簡結果。 它們也可以繫結至控制項,讓使用者輕鬆地檢視和修改查詢結果。
例如,下列程式碼範例顯示的 LINQ 查詢,會從集合中傳回一份客戶清單,並根據位置分組。
' Obtain a list of customers.
Dim customers As List(Of Customer) = GetCustomers()
' Return customers that are grouped based on country.
Dim countries = From cust In customers
Order By cust.Country, cust.City
Group By CountryName = cust.Country
Into CustomersInCountry = Group, Count()
Order By CountryName
' Output the results.
For Each country In countries
Debug.WriteLine(country.CountryName & " count=" & country.Count)
For Each customer In country.CustomersInCountry
Debug.WriteLine(" " & customer.CompanyName & " " & customer.City)
Next
Next
' Output:
' Canada count=2
' Contoso, Ltd Halifax
' Fabrikam, Inc. Vancouver
' United States count=1
' Margie's Travel Redmond
執行範例
執行簡介和 LINQ 查詢結構一節中的範例,包括下列程式碼,會傳回客戶和訂單清單。
' Return a list of customers.
Private Function GetCustomers() As List(Of Customer)
Return New List(Of Customer) From
{
New Customer With {.CustomerID = 1, .CompanyName = "Contoso, Ltd", .City = "Halifax", .Country = "Canada"},
New Customer With {.CustomerID = 2, .CompanyName = "Margie's Travel", .City = "Redmond", .Country = "United States"},
New Customer With {.CustomerID = 3, .CompanyName = "Fabrikam, Inc.", .City = "Vancouver", .Country = "Canada"}
}
End Function
' Return a list of orders.
Private Function GetOrders() As List(Of Order)
Return New List(Of Order) From
{
New Order With {.CustomerID = 1, .Amount = "200.00"},
New Order With {.CustomerID = 3, .Amount = "600.00"},
New Order With {.CustomerID = 1, .Amount = "300.00"},
New Order With {.CustomerID = 2, .Amount = "100.00"},
New Order With {.CustomerID = 3, .Amount = "800.00"}
}
End Function
' Customer Class.
Private Class Customer
Public Property CustomerID As Integer
Public Property CompanyName As String
Public Property City As String
Public Property Country As String
End Class
' Order Class.
Private Class Order
Public Property CustomerID As Integer
Public Property Amount As Decimal
End Class
LINQ 提供者
LINQ 提供者會對應 Visual Basic LINQ 查詢和查詢中的資料來源。 當您撰寫 LINQ 查詢時,提供者會接受該查詢,並將它轉譯成資料來源能夠執行的命令。 提供者也會將資料從來源轉換成組成查詢結果的物件。 最後,當您將更新傳送至資料來源時,它會將物件轉換成資料。
Visual Basic 包含下列 LINQ 提供者。
提供者 | 描述 |
---|---|
LINQ to Objects | LINQ to Objects 提供者讓您查詢記憶體內部的集合和陣列。 如果物件支援 IEnumerable 或 IEnumerable<T> 介面,LINQ to Objects 提供者就會讓您查詢。 匯入 System.Linq 命名空間就可以啟用 LINQ to Objects 提供者,所有 Visual Basic 專案都預設匯入。 如需 LINQ to Objects 提供者的詳細資訊,請參閱 LINQ to Objects。 |
LINQ to SQL | LINQ to SQL 提供者可讓您查詢及修改 SQL Server 資料庫中的資料。 這可讓您輕鬆對應應用程式的物件模型與資料庫的資料表和物件。 Visual Basic 納入物件關聯式設計工具 (O/R 設計工具),讓 LINQ to SQL 更好用。 這個設計工具是用於在對應至資料庫物件的應用程式中建立物件模型。 O/R 設計工具也提供將預存程序和函式對應至 DataContext 物件的功能,該工具會管理與資料庫的通訊,並且儲存開放式並行存取檢查的狀態。 如需 LINQ to SQL 提供者的詳細資訊,請參閱 LINQ to SQL。 如需物件關聯式設計工具的詳細資訊,請參閱 Visual Studio 中的 LINQ to SQL 工具。 |
LINQ to XML | LINQ to XML 提供者可讓您查詢及修改 XML。 您可以修改記憶體內部的 XML,也可以從檔案載入 XML 並將 XML 儲存到檔案。 此外,LINQ to XML 提供者也會啟用 XML 常值和 XML 軸屬性,讓您直接在 Visual Basic 程式碼中撰寫 XML。 如需詳細資訊,請參閱 XML。 |
LINQ to DataSet | LINQ to DataSet 提供者可讓您查詢及更新 ADO.NET 資料集中的資料。 您可以將 LINQ 的強大功能加入使用資料集的應用程式,以簡化並擴充查詢、彙總及更新資料集資料的能力。 如需詳細資訊,請參閱 LINQ to DataSet。 |
LINQ 查詢的結構
LINQ 查詢,通常稱為「查詢運算式」,由識別查詢的資料來源和反覆運算變數的查詢子句組合而成。 查詢運算式也可以包含排序、篩選、群組和聯結的指示,或套用至來源資料的計算。 查詢運算式語法類似於 SQL 語法,所以您會覺得大部分的語法很熟悉。
查詢運算式以 From
子句開頭。 這個子句會識別查詢和變數的來源資料,這些變數用於分別參考來源資料的每個項目。 這些變數稱為「範圍變數」或「反覆運算變數」。 查詢一定要有 From
子句,Aggregate
查詢除外,因為 From
子句對這類查詢為選擇性項目。 識別出 From
或 Aggregate
子句中的查詢範圍和來源之後,您可以包含任何查詢子句組合以精簡查詢。 如需查詢子句的詳細資訊,請參閱本主題後文中的 Visual Basic LINQ 查詢運算子。 例如,下列查詢會將客戶資料的來源集合識別為 customers
變數,而反覆運算變數則稱之為 cust
。
Dim customers = GetCustomers()
Dim queryResults = From cust In customers
For Each result In queryResults
Debug.WriteLine(result.CompanyName & " " & result.Country)
Next
' Output:
' Contoso, Ltd Canada
' Margie's Travel United States
' Fabrikam, Inc. Canada
這個範例本身就是個有效的查詢;但是當您加入更多的查詢子句來精簡結果時,查詢就會變得更強大。 例如,您可以加入 Where
子句,根據一或多個值來篩選結果。 查詢運算式是單行程式碼,您只可以將其他查詢子句附加至查詢結尾。 您可以使用底線 (_) 行接續字元,將查詢分割成多行文字,以提高可讀性。 下列程式碼範例顯示的查詢範例,包含 Where
子句。
Dim queryResults = From cust In customers
Where cust.Country = "Canada"
另一個功能強大的查詢子句是 Select
子句,可讓您只傳回從資料來源選取的欄位。 LINQ 查詢會傳回可列舉的強類型物件集合。 查詢可以傳回匿名類型或具名類型的集合。 您可以使用 Select
子句,只傳回資料來源的單一欄位。 當您這麼做時,傳回的集合類型就是該單一欄位的類型。 您也可以使用 Select
子句,傳回資料來源的多個欄位。 當您這麼做時,傳回的集合類型就是新的匿名類型。 您也可以比對查詢傳回的欄位和指定的具名類型欄位。 下列程式碼範例顯示傳回匿名類型集合的查詢運算式,該類型具有填入來自資料來源之選取欄位資料的成員。
Dim queryResults = From cust In customers
Where cust.Country = "Canada"
Select cust.CompanyName, cust.Country
LINQ 查詢也可以用來結合多個資料來源,並傳回單一結果。 使用一或多個 From
子句,或使用 Join
或 Group Join
查詢子句,即可完成。 下列程式碼範例顯示的查詢運算式,結合了客戶和訂單資料,並傳回包含客戶和訂單資料的匿名類型集合。
Dim customers = GetCustomers()
Dim orders = GetOrders()
Dim queryResults = From cust In customers, ord In orders
Where cust.CustomerID = ord.CustomerID
Select cust, ord
For Each result In queryResults
Debug.WriteLine(result.ord.Amount & " " & result.ord.CustomerID & " " & result.cust.CompanyName)
Next
' Output:
' 200.00 1 Contoso, Ltd
' 300.00 1 Contoso, Ltd
' 100.00 2 Margie's Travel
' 600.00 3 Fabrikam, Inc.
' 800.00 3 Fabrikam, Inc.
您可以使用 Group Join
子句建立階層式的查詢結果,其包含客戶物件的集合。 每個客戶物件都有一個屬性,包含該客戶所有訂單的集合。 下列程式碼範例顯示的查詢運算式,結合了階層式結果的客戶和訂單資料,並傳回匿名類型的集合。 查詢傳回的類型包含 CustomerOrders
屬性,內含客戶訂單資料的集合。 它也包含 OrderTotal
屬性,內含該客戶所有訂單小計的總和。 (這個查詢相當於 LEFT OUTER JOIN)。
Dim customers = GetCustomers()
Dim orders = GetOrders()
Dim queryResults = From cust In customers
Group Join ord In orders On
cust.CustomerID Equals ord.CustomerID
Into CustomerOrders = Group,
OrderTotal = Sum(ord.Amount)
Select cust.CompanyName, cust.CustomerID,
CustomerOrders, OrderTotal
For Each result In queryResults
Debug.WriteLine(result.OrderTotal & " " & result.CustomerID & " " & result.CompanyName)
For Each ordResult In result.CustomerOrders
Debug.WriteLine(" " & ordResult.Amount)
Next
Next
' Output:
' 500.00 1 Contoso, Ltd
' 200.00
' 300.00
' 100.00 2 Margie's Travel
' 100.00
' 1400.00 3 Fabrikam, Inc.
' 600.00
' 800.00
另有幾個 LINQ 查詢運算子,可讓您建立功能強大的查詢運算式。 本主題的下一節,將討論查詢運算式中可包含的各種查詢子句。 如需 Visual Basic 查詢子句的詳細資訊,請參閱查詢。
Visual Basic LINQ 查詢運算子
System.Linq 命名空間和其他支援 LINQ 查詢的命名空間中的類別,包含了依應用程式需求建立並精簡查詢的呼叫方法。 Visual Basic 包含下列常見查詢子句的關鍵字。 如需 Visual Basic 查詢子句的詳細資訊,請參閱查詢。
From 子句
查詢必須有 From
子句或 Aggregate
子句才能開始。 From
子句會指定查詢的來源集合和反覆運算變數。 例如:
' Returns the company name for all customers for which
' the Country is equal to "Canada".
Dim names = From cust In customers
Where cust.Country = "Canada"
Select cust.CompanyName
Select 子句
選擇性。 Select
子句宣告一組查詢的反覆運算變數。 例如:
' Returns the company name and ID value for each
' customer as a collection of a new anonymous type.
Dim customerList = From cust In customers
Select cust.CompanyName, cust.CustomerID
如果不指定 Select
子句,則查詢的反覆運算變數即由 From
或 Aggregate
子句指定的反覆運算變數組成。
Where 子句
選擇性。 Where
子句指定查詢的篩選條件。 例如:
' Returns all product names for which the Category of
' the product is "Beverages".
Dim names = From product In products
Where product.Category = "Beverages"
Select product.Name
Order By 子句
選擇性。 Order By
子句指定查詢中資料行的排序次序。 例如:
' Returns a list of books sorted by price in
' ascending order.
Dim titlesAscendingPrice = From b In books
Order By b.price
Join 子句
選擇性。 Join
子句將兩個集合合併成單一集合。 例如:
' Returns a combined collection of all of the
' processes currently running and a descriptive
' name for the process taken from a list of
' descriptive names.
Dim processes = From proc In Process.GetProcesses
Join desc In processDescriptions
On proc.ProcessName Equals desc.ProcessName
Select proc.ProcessName, proc.Id, desc.Description
Group By 子句
選擇性。 Group By
子句將查詢結果的元素分組。 該子句可用來將彙總函式套用至每個群組。 例如:
' Returns a list of orders grouped by the order date
' and sorted in ascending order by the order date.
Dim orderList = From order In orders
Order By order.OrderDate
Group By OrderDate = order.OrderDate
Into OrdersByDate = Group
Group Join 子句
選擇性。 Group Join
子句將兩個集合合併成單一階層式集合。 例如:
' Returns a combined collection of customers and
' customer orders.
Dim customerList = From cust In customers
Group Join ord In orders On
cust.CustomerID Equals ord.CustomerID
Into CustomerOrders = Group,
TotalOfOrders = Sum(ord.Amount)
Select cust.CompanyName, cust.CustomerID,
CustomerOrders, TotalOfOrders
Aggregate 子句
查詢必須有 Aggregate
子句或 From
子句才能開始。 Aggregate
子句會將一或多個彙總函式套用至集合。 例如,您可以使用 Aggregate
子句來計算查詢所傳回的所有元素總和,如下列範例所示。
' Returns the sum of all order amounts.
Dim orderTotal = Aggregate order In orders
Into Sum(order.Amount)
也可以使用 Aggregate
子句修改查詢。 例如,您可以使用 Aggregate
子句執行相關查詢集合的計算。 例如:
' Returns the customer company name and largest
' order amount for each customer.
Dim customerMax = From cust In customers
Aggregate order In cust.Orders
Into MaxOrder = Max(order.Amount)
Select cust.CompanyName, MaxOrder
Let 子句
選擇性。 Let
子句計算值,並將其指派給查詢中的新變數。 例如:
' Returns a list of products with a calculation of
' a ten percent discount.
Dim discountedProducts = From prod In products
Let Discount = prod.UnitPrice * 0.1
Where Discount >= 50
Select prod.Name, prod.UnitPrice, Discount
Distinct 子句
選擇性。 Distinct
子句限制目前反覆運算變數的值,以消除查詢結果中重複的值。 例如:
' Returns a list of cities with no duplicate entries.
Dim cities = From item In customers
Select item.City
Distinct
Skip 子句
選擇性。 Skip
子句略過集合中指定數目的元素,然後傳回其餘元素。 例如:
' Returns a list of customers. The first 10 customers
' are ignored and the remaining customers are
' returned.
Dim customerList = From cust In customers
Skip 10
Skip While 子句
選擇性。 只要指定的條件為 true
,Skip While
子句便會略過集合中的元素,然後傳回其餘元素。 例如:
' Returns a list of customers. The query ignores all
' customers until the first customer for whom
' IsSubscriber returns false. That customer and all
' remaining customers are returned.
Dim customerList = From cust In customers
Skip While IsSubscriber(cust)
Take 子句
選擇性。 Take
子句從集合開頭傳回指定數目的連續元素。 例如:
' Returns the first 10 customers.
Dim customerList = From cust In customers
Take 10
Take While 子句
選擇性。 只要指定的條件為 true
,Take While
子句便會包含集合中的元素,並略過其餘元素。 例如:
' Returns a list of customers. The query returns
' customers until the first customer for whom
' HasOrders returns false. That customer and all
' remaining customers are ignored.
Dim customersWithOrders = From cust In customers
Order By cust.Orders.Count Descending
Take While HasOrders(cust)
使用其他 LINQ 查詢功能
透過呼叫 LINQ 提供的可列舉和可查詢類型的成員,您可以使用其他的 LINQ 查詢功能。 透過呼叫查詢運算式結果上的特定查詢運算子,您可以使用這些額外的功能。 例如,下列程式碼範例使用 Enumerable.Union 方法,將兩個查詢結果合併成一個查詢結果。 它使用 Enumerable.ToList 方法傳回泛型清單的查詢結果。
Public Function GetAllCustomers() As List(Of Customer)
Dim customers1 = From cust In domesticCustomers
Dim customers2 = From cust In internationalCustomers
Dim customerList = customers1.Union(customers2)
Return customerList.ToList()
End Function
如需其他 LINQ 功能的詳細資訊,請參閱標準查詢運算子概觀。
使用 LINQ to SQL 連接到資料庫
在 Visual Basic 中,您使用 LINQ to SQL 檔案識別要存取的 SQL Server 資料庫物件,例如資料表、檢視和預存程序。 LINQ to SQL 檔案的副檔名為 .dbml。
當您有 SQL Server 資料庫的有效連接時,可以將 [LINQ to SQL 類別] 項目範本加入專案。 這會顯示物件關聯式設計工具 (O/R 設計工具)。 O/R 設計工具可讓您將想要存取的程式碼項目,從 [伺服器總管]/[資料庫總管] 拖曳至設計工具介面上。 LINQ to SQL 檔案將 DataContext 物件加入專案。 此物件包含您想要存取的資料表和檢視的屬性和集合,以及您想要呼叫的預存程序方法。 將變更儲存至 LINQ to SQL (.dbml) 檔案之後,參考 O/R 設計工具所定義的 DataContext 物件,您就可以存取程式碼中的這些物件。 專案的 DataContext 物件依據您的 LINQ to SQL 檔案名稱來命名。 例如,名為 Northwind.dbml 的 LINQ to SQL 檔案,會建立名為 NorthwindDataContext
的 DataContext 物件。
如需逐步指示的範例,請參閱如何:查詢資料庫和如何:呼叫預存程序。
支援 LINQ 的 Visual Basic 功能
Visual Basic 包含其他值得注意的功能,讓 LINQ 簡單易用,並減少為執行 LINQ 查詢所必須撰寫的程式碼數量。 其中包括下列各項:
匿名類型:可讓您根據查詢結果建立新的類型。
隱含類型變數:可讓您延後指定類型,並讓編譯器根據查詢結果推斷類型。
擴充方法:可讓您以自己的方法擴充現有的類型,卻不修改類型本身。
如需詳細資訊,請參閱支援 LINQ 的 Visual Basic 功能。
延期與立即執行查詢
查詢執行會與建立查詢分開。 查詢建立之後,會另有機制觸發執行。 查詢一經定義便可執行 (「立即執行」),或者儲存定義以待稍後執行查詢 (「延後執行」)。
當您建立查詢時,查詢本身預設不會立即執行。 反而會將查詢定義儲存在變數中,用以參考查詢結果。 稍後存取程式碼中的查詢結果變數時,例如在 For…Next
迴圈中,就會執行查詢。 此程序稱為「延後執行」。
查詢也可以在定義當時執行,這稱為「立即執行」。 套用要求存取查詢結果個別項目的方法,可觸發立即執行。 這個結果可能會包括彙總函式,例如 Count
、Sum
、Average
、Min
或 Max
。 如需彙總函式的詳細資訊,請參閱 Aggregate 子句。
使用 ToList
或 ToArray
方法也會強制立即執行。 當您想要立即執行查詢並快取結果時,這方法非常好用。 如需這些方法的詳細資訊,請參閱轉換資料類型。
如需查詢執行的詳細資訊,請參閱撰寫第一個 LINQ 查詢。
Visual Basic 中的 XML
Visual Basic 中的 XML 功能包括 XML 常值和 XML 軸屬性,讓您輕鬆建立、存取、查詢及修改程式碼中的 XML。 XML 常值可讓您直接在程式碼中撰寫 XML。 Visual Basic 編譯器將 XML 視為第一級的資料物件。
下列程式碼範例示範如何建立 XML 項目、存取其子項目和屬性,以及使用 LINQ 查詢項目內容。
' Place Imports statements at the top of your program.
Imports <xmlns:ns="http://SomeNamespace">
Module Sample1
Sub SampleTransform()
' Create test by using a global XML namespace prefix.
Dim contact =
<ns:contact>
<ns:name>Patrick Hines</ns:name>
<ns:phone ns:type="home">206-555-0144</ns:phone>
<ns:phone ns:type="work">425-555-0145</ns:phone>
</ns:contact>
Dim phoneTypes =
<phoneTypes>
<%= From phone In contact.<ns:phone>
Select <type><%= phone.@ns:type %></type>
%>
</phoneTypes>
Console.WriteLine(phoneTypes)
End Sub
End Module
如需詳細資訊,請參閱 XML。
相關資源
主題 | 說明 |
---|---|
XML | 說明 Visual Basic 中可查詢的 XML 功能,它們還可讓您在 Visual Basic 程式碼中將 XML 當做第一級資料物件納入。 |
查詢 | 提供 Visual Basic 中的查詢子句參考資訊。 |
LINQ (Language-Integrated Query) | 包含 LINQ 的一般資訊、程式設計指南和範例。 |
LINQ to SQL | 包含 LINQ to SQL 的一般資訊、程式設計指南和範例。 |
LINQ to Objects | 包含 LINQ to Objects 的一般資訊、程式設計指南和範例。 |
LINQ to ADO.NET (入口網站頁面) | 包含 LINQ to ADO.NET 的一般資訊、程式設計指南和範例連結。 |
LINQ to XML | 包含 LINQ to XML 的一般資訊、程式設計指南和範例。 |
如何和逐步解說主題
如何:指派用來執行更新、插入和刪除的預存程序 (O/R 設計工具)
精選書籍章節
程式設計 Visual Basic 2008 中的第 17 章:LINQ
另請參閱
- LINQ (Language-Integrated Query)
- Visual Basic 中的 LINQ to XML 概觀
- LINQ to DataSet 概觀
- LINQ to SQL
- LINQ to SQL Tools in Visual Studio (Visual Studio 中的 LINQ to SQL 工具)
- DataContext 方法 (O/R 設計工具)