Share via


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

Visual Basic には、コレクション間で共通する値に基づいて複数のコレクションの内容を結合できる、Join クエリ句と Group Join クエリ句があります。 これらの値をキー値と呼びます。 リレーショナル データベースの考え方に慣れている開発者の場合は、実質的に、Join 句を INNER JOIN、Group Join 句を LEFT OUTER JOIN と考えることができます。

このトピックでは、Join クエリ句と Group 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 句を使用して内部結合を実行するには

  • 次のコードをプロジェクトの 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 句は、実質的に LEFT OUTER JOIN を実行します。 一般に LEFT OUTER JOIN として知られているものと Group Join 句が返すものとの違いは、Group Join 句では、結合の右側のコレクションから得た結果を、左側のコレクションの項目ごとにグループ化することです。 リレーショナル データベースでは、LEFT OUTER 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
    

コードの実行

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

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

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

参照

参照

Join 句 (Visual Basic)

Group Join 句 (Visual Basic)

From 句 (Visual Basic)

Where 句 (Visual Basic)

概念

Visual Basic における LINQ の概要

LINQ によるデータ変換 (C#)

その他の技術情報

LINQ (Visual Basic)

クエリ (Visual Basic)

履歴の変更

日付

履歴

理由

2011 年 3 月

コード例の出力コメントの場所が変更され、別のコード例に出力コメントが追加されました。

カスタマー フィードバック