How to: Combine Data with LINQ by Using Joins - Visual Basic (original) (raw)
Visual Basic provides the Join
and Group Join
query clauses to enable you to combine the contents of multiple collections based on common values between the collections. These values are known as key values. Developers familiar with relational database concepts will recognize the Join
clause as an INNER JOIN and the Group Join
clause as, effectively, a LEFT OUTER JOIN.
The examples in this topic demonstrate a few ways to combine data by using the Join
and Group Join
query clauses.
Create a Project and Add Sample Data
To create a project that contains sample data and types
- To run the samples in this topic, open Visual Studio and add a new Visual Basic Console Application project. Double-click the Module1.vb file created by Visual Basic.
- The samples in this topic use the
Person
andPet
types and data from the following code example. Copy this code into the defaultModule1
module created by Visual Basic.
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
Perform an Inner Join by Using the Join Clause
An INNER JOIN combines data from two collections. Items for which the specified key values match are included. Any items from either collection that do not have a matching item in the other collection are excluded.
In Visual Basic, LINQ provides two options for performing an INNER JOIN: an implicit join and an explicit join.
An implicit join specifies the collections to be joined in a From
clause and identifies the matching key fields in a Where
clause. Visual Basic implicitly joins the two collections based on the specified key fields.
You can specify an explicit join by using the Join
clause when you want to be specific about which key fields to use in the join. In this case, a Where
clause can still be used to filter the query results.
To perform an Inner Join by using the Join clause
- Add the following code to the
Module1
module in your project to see examples of both an implicit and explicit inner join.
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
Perform a Left Outer Join by Using the Group Join Clause
A LEFT OUTER JOIN includes all the items from the left-side collection of the join and only matching values from the right-side collection of the join. Any items from the right-side collection of the join that do not have a matching item in the left-side collection are excluded from the query result.
The Group Join
clause performs, in effect, a LEFT OUTER JOIN. The difference between what is typically known as a LEFT OUTER JOIN and what the Group Join
clause returns is that the Group Join
clause groups results from the right-side collection of the join for each item in the left-side collection. In a relational database, a LEFT OUTER JOIN returns an ungrouped result in which each item in the query result contains matching items from both collections in the join. In this case, the items from the left-side collection of the join are repeated for each matching item from the right-side collection. You will see what this looks like when you complete the next procedure.
You can retrieve the results of a Group Join
query as an ungrouped result by extending your query to return an item for each grouped query result. To accomplish this, you have to ensure that you query on the DefaultIfEmpty
method of the grouped collection. This ensures that items from the left-side collection of the join are still included in the query result even if they have no matching results from the right-side collection. You can add code to your query to provide a default result value when there is no matching value from the right-side collection of the join.
To perform a Left Outer Join by using the Group Join clause
- Add the following code to the
Module1
module in your project to see examples of both a grouped left outer join and an ungrouped left outer join.
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
Perform a Join by Using a Composite Key
You can use the And
keyword in a Join
or Group Join
clause to identify multiple key fields to use when matching values from the collections being joined. The And
keyword specifies that all specified key fields must match for items to be joined.
To perform a Join by using a composite key
- Add the following code to the
Module1
module in your project to see examples of a join that uses a composite key.
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
Run the Code
To add code to run the examples
- Replace the
Sub Main
in theModule1
module in your project with the following code to run the examples in this topic.
Sub Main()
InnerJoinExample()
LeftOuterJoinExample()
CompositeKeyJoinExample()
Console.ReadLine()
End Sub
- Press F5 to run the examples.