Visual Basic 提供
Join
和
Group Join
查询子句,使你能够根据集合之间的公用值组合多个集合的内容。 这些值称为键值。 熟悉关系数据库概念的开发人员会将
Join
子句识别为内部联接,而
Group Join
子句实际上是左外部联接。
本主题中的示例演示了使用
Join
和
Group Join
查询子句合并数据的几种方法。
创建项目并添加示例数据
创建包含示例数据和类型的项目
若要运行本主题中的示例,请打开 Visual Studio 并添加新的 Visual Basic 控制台应用程序项目。 双击 Visual Basic 创建的 Module1 文件。
本主题中的示例使用以下代码示例中的
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
内部联接合并了两个集合中的数据。 指定键值相匹配的项包含在内。 任一集合中在另一个集合中没有匹配项的任何项都会排除。
在 Visual Basic 中,LINQ 提供了两种用于执行内部联接的选项:隐式联接和显式联接。
隐式连接指定要在 From
子句中联接的集合,并在 Where
子句中标识匹配的键字段。 Visual Basic 根据指定的键字段隐式联接两个集合。
如需了解要在联接中使用哪些键字段时,可以使用 Join
子句来指定显式联接。 在这种情况下,仍可以使用 Where
子句来筛选查询结果。
将以下代码添加到项目中的 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)
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)
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
查询的结果作为未分组结果检索。 为此,必须确保对分组集合的 DefaultIfEmpty
方法进行查询。 这可确保联接左侧集合中的项仍包含在查询结果中,即使它们没有右侧集合中的匹配结果。 可以向查询中添加代码,以便在联接的右侧集合中没有匹配值时提供默认结果值。
将以下代码添加到项目中的 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)
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)
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)
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 运行示例。
Visual Basic 中的 LINQ 简介
Join 子句
Group Join 子句
From 子句
Where 子句
使用 LINQ 进行数据转换 (C#)
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:https://aka.ms/ContentUserFeedback。
提交和查看相关反馈