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

更新 : 2007 年 11 月

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 _firstName As String
      Public _lastName As String
    
      Public Property FirstName() As String
        Get
          Return _firstName
        End Get
        Set(ByVal value As String)
          _firstName = value
        End Set
      End Property
    
      Public Property LastName() As String
        Get
          Return _lastName
        End Get
        Set(ByVal value As String)
          _lastName = value
        End Set
      End Property
    End Class
    
    Class Pet
      Public _name As String
      Public _owner As Person
    
      Public Property Name() As String
        Get
          Return _name
        End Get
        Set(ByVal value As String)
          _name = value
        End Set
      End Property
    
      Public Property Owner() As Person
        Get
          Return _owner
        End Get
        Set(ByVal value As Person)
          _owner = value
        End Set
      End Property
    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)
    
      ' "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)
      ' This code produces the following output:
      '
      ' Magnus:
      '     Daisy
      ' Terry:
      '     Barley
      '     Boots
      '     Blue Moon
      ' Charlotte:
      '     Whiskers
      ' Arlene:
    
    
      ' 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())
    End Sub
    
    ' This code produces the following output:
    '
    ' Magnus:       Daisy
    ' Terry:        Barley
    ' Terry:        Boots
    ' Terry:        Blue Moon
    ' Charlotte:    Whiskers
    ' Arlene:     
    

複合キーを使用した結合の実行

結合するコレクションの値を一致させるときに、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)
    End Sub
    

コードの実行

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

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

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

参照

概念

Visual Basic における LINQ の概要

参照

Join 句 (Visual Basic)

Group Join 句 (Visual Basic)

From 句 (Visual Basic)

Where 句 (Visual Basic)

その他の技術情報

LINQ (Visual Basic)

クエリ (Visual Basic)