方法 : LINQ の結合を使用してデータを結合する (Visual Basic)
Visual Basic には、コレクション間で共通する値に基づいて複数のコレクションの内容を結合できる、Join クエリ句と Group Join クエリ句があります。 これらの値をキー値と呼びます。 リレーショナル データベースの考え方に慣れている開発者の場合は、実質的に、Join 句を INNER JOIN、Group Join 句を LEFT OUTER JOIN と考えることができます。
このトピックでは、Join クエリ句と Group Join クエリ句を使用してデータを結合する方法の例を示して説明します。
プロジェクトの作成とサンプル データの追加
サンプル データと型を含むプロジェクトを作成するには
このトピックのサンプルを実行するには、Visual Studio を開き、新しい Visual Basic コンソール アプリケーション プロジェクトを追加します。 Visual Basic で作成された Module1.vb ファイルをダブルクリックします。
このトピックのサンプルでは、次のコード例の 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
コードの実行
コード例を実行するためにコードを追加するには
このトピックのコード例を実行するには、プロジェクト内のModule1 モジュールの Sub Main を、次のコードに置き換えます。
Sub Main() InnerJoinExample() LeftOuterJoinExample() CompositeKeyJoinExample() Console.ReadLine() End Sub
F5 キーを押して、コード例を実行します。