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 提供者,System.Linq 命名空間預設會在所有 Visual Basic 專案中被匯入。 如需 LINQ to Objects 提供者的詳細資訊,請參閱 LINQ to Objects。 |
LINQ to SQL | LINQ to SQL 提供者可讓您查詢和修改 SQL Server 資料庫中的數據。 這可讓您輕鬆地將應用程式的物件模型對應至資料庫中的數據表和物件。 Visual Basic 可讓您更輕鬆地使用 LINQ to SQL,方法是包含物件關係型設計工具 (O/R 設計工具)。 此設計工具可用來在對應至資料庫中物件的應用程式中建立物件模型。 O/R 設計工具也提供將預存程序和函式對應至 DataContext 物件的功能,以管理與資料庫的通訊,並儲存樂觀並行檢查的狀態。 如需 LINQ to SQL 提供者的詳細資訊,請參閱 LINQ to SQL。 如需對象關係型設計工具的詳細資訊,請參閱 Visual Studio中的LINQ to SQL Tools。 |
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
子句會宣告查詢的一組迭代變數。 例如:
' 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
子句或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
子句會略過集合中指定數量的元素,然後返回剩餘的元素。 例如:
' 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
略過 While 子句
選擇性。
Skip While
子句會略過集合中的專案,只要指定的條件為 true
,然後傳回剩餘的專案。 例如:
' 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
句會從集合開頭傳回指定的連續項目數目。 例如:
' Returns the first 10 customers.
Dim customerList = From cust In customers
Take 10
Take While 子句
選擇性。
Take While
子句會在集合中包含專案,只要指定的條件為 true
,就會略過其餘專案。 例如:
' 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) 檔案之後,您可以藉由參考 DataContext O/R 設計工具所定義的物件,在程式碼中存取這些物件。
DataContext項目的物件會根據 LINQ to SQL 檔案的名稱來命名。 例如,名為 Northwind.dbml 的 LINQ to SQL 檔案會建立 DataContext 名為 NorthwindDataContext
的物件。
如需逐步指示的範例,請參閱 如何:查詢資料庫 和 如何:呼叫預存程式。
支援 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 (語言整合查詢) | 包含 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 設計工具)
精選書籍章節
第 17 章:Visual Basic 2008 程式設計中的 LINQ