方法: LINQ の結合を使用してデータを結合する (Visual Basic)

Visual Basic では、コレクション間の共通値に基づいて複数のコレクションの内容を結合できるようにするための、Join および Group Join クエリ句が提供されます。 これらの値は "キー" 値と呼ばれます。 リレーショナル データベースの概念をよく理解している開発者は、Join 句を内部結合として認識し、Group Join 句を実質的に左外部結合として認識します。

このトピックの例では、JoinGroup Join のクエリ句を使用してデータを結合するいくつかの方法を示します。

プロジェクトを作成してサンプル データを追加する

サンプルのデータと種類を含むプロジェクトを作成するには

  1. このトピックのサンプルを実行するには、Visual Studio を開き、新しい Visual Basic コンソール アプリケーションのプロジェクトを追加します。 Visual Basic によって作成された Module1.vb ファイルをダブルクリックします。

  2. このトピックのサンプルでは、次のコード例の 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 句を使用して内部結合を実行する

内部結合では、2 つのコレクションのデータを結合します。 指定されたキー値が一致する項目が含まれます。 いずれかのコレクションの項目のうち、他のコレクションに一致する項目がないものは除外されます。

Visual Basic では、LINQ で内部結合を実行するためのオプションとして、暗黙的な結合と明示的な結合という 2 つが提供されます。

暗黙的な結合では、From 句で結合されるコレクションを指定し、Where 句で一致するキー フィールドを識別します。 Visual Basic では、指定されたキー フィールドに基づいて、2 つのコレクションを暗黙的に結合します。

結合で使用するキー フィールドを特定する場合は、Join 句を使用して明示的な結合を指定できます。 この場合も、Where 句を使用してクエリ結果をフィルター処理できます。

Join 句を使用して内部結合を実行するには

  1. 次のコードをプロジェクトの 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 句では、左側のコレクションの項目ごとに、結合の右側のコレクションからの結果がグループ化されることです。 リレーショナル データベースでは、左外部結合でグループ化されていない結果が返されます。この場合、クエリ結果の各項目には、結合の両方のコレクションの一致する項目が含まれます。 この場合、結合の左側のコレクションの項目が、右側のコレクションの一致する項目ごとに繰り返されます。 次の手順を完了すると、このようになるのがわかります。

クエリを拡張してグループ化されたクエリ結果ごとに 1 つの項目を返すようにすることで、Group Join クエリの結果をグループ化されていない結果として取得できます。 そのためには、グループ化されたコレクションの DefaultIfEmpty メソッドに対してクエリを確実に実行する必要があります。 これにより、右側のコレクションに一致する結果がない場合でも、確実に結合の左側のコレクションの項目がクエリ結果に引き続き含まれるようになります。 結合の右側のコレクションに一致する値がない場合は、クエリにコードを追加して既定の結果値を指定できます。

Group Join 句を使用して左外部結合を実行するには

  1. 次のコードをプロジェクトの 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 キーワードでは、結合される項目について、指定されたすべてのキー フィールドが一致する必要があることを指定します。

複合キーを使用して結合を実行するには

  1. 次のコードをプロジェクトの 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
    

コードを実行する

例を実行するコードを追加するには

  1. プロジェクトの Module1 モジュールの Sub Main を次のコードに置き換えて、このトピックの例を実行します。

    Sub Main()
        InnerJoinExample()
        LeftOuterJoinExample()
        CompositeKeyJoinExample()
    
        Console.ReadLine()
    End Sub
    
  2. F5 キーを押して例を実行します。

関連項目