如何:使用 Joins 以 LINQ 合併資料 (Visual Basic)
Visual Basic 提供 Join
和 Group Join
查詢子句,可讓您根據集合之間的通用值來合併多個集合的內容。 這些值稱為「索引鍵」值。 熟悉關聯式資料庫概念的開發人員會將 Join
子句視為「內部聯結」,並將 Group Join
子句視為實際上是「左方外部聯結」。
本主題中的範例示範使用 Join
和 Group Join
查詢子句來合併資料的幾個方式。
建立專案並新增範例資料
建立包含範例資料和類型的專案
若要執行本主題中的範例,請開啟 Visual Studio 並新增 Visual Basic 主控台應用程式專案。 按兩下 Visual Basic 所建立的 Module1.vb 檔案。
本主題中的範例會使用下列程式碼範例中的
Person
和Pet
類型和資料。 將此程式碼複製到 Visual Basic 所建立的預設Module1
模組。Private _people As List(Of Person) Private _pets As List(Of Pet) Function GetPeople() As List(Of Person) If _people Is Nothing Then CreateLists() Return _people End Function Function GetPets(ByVal people As List(Of Person)) As List(Of Pet) If _pets Is Nothing Then CreateLists() Return _pets End Function Private Sub CreateLists() Dim pers As Person _people = New List(Of Person) _pets = New List(Of Pet) pers = New Person With {.FirstName = "Magnus", .LastName = "Hedlund"} _people.Add(pers) _pets.Add(New Pet With {.Name = "Daisy", .Owner = pers}) pers = New Person With {.FirstName = "Terry", .LastName = "Adams"} _people.Add(pers) _pets.Add(New Pet With {.Name = "Barley", .Owner = pers}) _pets.Add(New Pet With {.Name = "Boots", .Owner = pers}) _pets.Add(New Pet With {.Name = "Blue Moon", .Owner = pers}) pers = New Person With {.FirstName = "Charlotte", .LastName = "Weiss"} _people.Add(pers) _pets.Add(New Pet With {.Name = "Whiskers", .Owner = pers}) ' Add a person with no pets for the sake of Join examples. _people.Add(New Person With {.FirstName = "Arlene", .LastName = "Huff"}) pers = New Person With {.FirstName = "Don", .LastName = "Hall"} ' Do not add person to people list for the sake of Join examples. _pets.Add(New Pet With {.Name = "Spot", .Owner = pers}) ' Add a pet with no owner for the sake of Join examples. _pets.Add(New Pet With {.Name = "Unknown", .Owner = New Person With {.FirstName = String.Empty, .LastName = String.Empty}}) End Sub
Class Person Public Property FirstName As String Public Property LastName As String End Class Class Pet Public Property Name As String Public Property Owner As Person End Class
使用 Join 子句執行內部聯結
「內部聯結」會合併兩個集合的資料。 其會包含與指定索引鍵值相符的項目。 如果任一集合中有任何項目在另一個集合中沒有相符項目,則排除這些項目。
在 Visual Basic 中,LINQ 提供兩個執行「內部聯結」的選項:隱含聯結和明確聯結。
隱含聯結會指定要在 From
子句中聯結的集合,並識別 Where
子句中的相符索引鍵欄位。 Visual Basic 會根據指定的索引鍵欄位隱含聯結這兩個集合。
當您想要明確指出要在聯結中使用的索引鍵欄位時,可以使用 Join
子句來指定明確聯結。 在此情況下,仍可使用 Where
子句來篩選查詢結果。
使用 Join 子句執行內部聯結
將下列程式碼新增至專案中的
Module1
模組,以查看隱含和明確內部聯結的範例。Sub InnerJoinExample() ' Create two lists. Dim people = GetPeople() Dim pets = GetPets(people) ' Implicit Join. Dim petOwners = From pers In people, pet In pets Where pet.Owner Is pers Select pers.FirstName, PetName = pet.Name ' Display grouped results. Dim output As New System.Text.StringBuilder For Each pers In petOwners output.AppendFormat( pers.FirstName & ":" & vbTab & pers.PetName & vbCrLf) Next Console.WriteLine(output) ' Explicit Join. Dim petOwnersJoin = From pers In people Join pet In pets On pet.Owner Equals pers Select pers.FirstName, PetName = pet.Name ' Display grouped results. output = New System.Text.StringBuilder() For Each pers In petOwnersJoin output.AppendFormat( pers.FirstName & ":" & vbTab & pers.PetName & vbCrLf) Next Console.WriteLine(output) ' Both queries produce the following output: ' ' Magnus: Daisy ' Terry: Barley ' Terry: Boots ' Terry: Blue Moon ' Charlotte: Whiskers End Sub
使用 Group Join 子句執行左方外部聯結
「左方外部聯結」會包含聯結左側集合中的所有項目,以及合聯結右側集合中僅相符的值。 如果聯結右側集合中有任何項目在左側集合中沒有相符項目,則從查詢結果中排除這些項目。
Group Join
子句實際上會執行「左方外部聯結」。 一般所稱的「左方外部聯結」與 Group Join
子句的差別在於,Group Join
子句會針對聯結左側集合中的每個項目,分組右側集合中的結果。 在關聯式資料庫中,「左方外部聯結」會傳回未分組的結果,其中查詢結果中的每個項目都會包含所聯結兩個集合中的相符項目。 在此情況下,聯結左側集合中的項目會針對右側集合中的每個相符項目重複。 當您完成下一個程序時,您會看到這看起來的樣子。
您可以將 Group Join
查詢的結果作為未分組的結果來擷取,方法是擴充您的查詢,以針對每個分組查詢結果傳回一個項目。 若要達成此目的,您必須確定在分組集合的 DefaultIfEmpty
方法上進行查詢。 這可確保聯結左側集合中的項目即使在右側集合中沒有相符結果,仍會包含在查詢結果中。 您可以將程式碼新增至查詢,以在聯結右側集合中沒有相符的值時提供預設結果值。
使用 Group Join 子句執行左方外部聯結
將下列程式碼新增至專案中的
Module1
模組,以查看分組左方外部聯結與未分組左方外部聯結的範例。Sub LeftOuterJoinExample() ' Create two lists. Dim people = GetPeople() Dim pets = GetPets(people) ' Grouped results. Dim petOwnersGrouped = From pers In people Group Join pet In pets On pers Equals pet.Owner Into PetList = Group Select pers.FirstName, pers.LastName, PetList ' Display grouped results. Dim output As New System.Text.StringBuilder For Each pers In petOwnersGrouped output.AppendFormat(pers.FirstName & ":" & vbCrLf) For Each pt In pers.PetList output.AppendFormat(vbTab & pt.Name & vbCrLf) Next Next Console.WriteLine(output) ' This code produces the following output: ' ' Magnus: ' Daisy ' Terry: ' Barley ' Boots ' Blue Moon ' Charlotte: ' Whiskers ' Arlene: ' "Flat" results. Dim petOwners = From pers In people Group Join pet In pets On pers Equals pet.Owner Into PetList = Group From pet In PetList.DefaultIfEmpty() Select pers.FirstName, pers.LastName, PetName = If(pet Is Nothing, String.Empty, pet.Name) ' Display "flat" results. output = New System.Text.StringBuilder() For Each pers In petOwners output.AppendFormat( pers.FirstName & ":" & vbTab & pers.PetName & vbCrLf) Next Console.WriteLine(output.ToString()) ' This code produces the following output: ' ' Magnus: Daisy ' Terry: Barley ' Terry: Boots ' Terry: Blue Moon ' Charlotte: Whiskers ' Arlene: End Sub
使用複合索引鍵執行聯結
您可以使用 Join
或 Group Join
子句中的 And
關鍵字來識別多個索引鍵欄位,以在比對聯結集合中的值時使用。 And
關鍵字指定必須符合所有指定的索引鍵欄位,才能聯結項目。
使用複合索引鍵執行聯結
將下列程式碼新增至專案中的
Module1
模組,以查看使用複合索引鍵的聯結範例。Sub CompositeKeyJoinExample() ' Create two lists. Dim people = GetPeople() Dim pets = GetPets(people) ' Implicit Join. Dim petOwners = From pers In people Join pet In pets On pet.Owner.FirstName Equals pers.FirstName And pet.Owner.LastName Equals pers.LastName Select pers.FirstName, PetName = pet.Name ' Display grouped results. Dim output As New System.Text.StringBuilder For Each pers In petOwners output.AppendFormat( pers.FirstName & ":" & vbTab & pers.PetName & vbCrLf) Next Console.WriteLine(output) ' This code produces the following output: ' ' Magnus: Daisy ' Terry: Barley ' Terry: Boots ' Terry: Blue Moon ' Charlotte: Whiskers End Sub
執行程式碼
新增程式碼以執行範例
將專案中
Module1
模組的Sub Main
取代為下列程式碼,以執行本主題中的範例。Sub Main() InnerJoinExample() LeftOuterJoinExample() CompositeKeyJoinExample() Console.ReadLine() End Sub
按 F5 鍵執行範例。