Postupy: Kombinace dat s LINQ pomocí spojení (Visual Basic)

Visual Basic poskytuje Join klauzule a Group Join klauzule dotazu, které umožňují kombinovat obsah více kolekcí na základě společných hodnot mezi kolekcemi. Tyto hodnoty se označují jako hodnoty klíče . Vývojáři, kteří jsou obeznámeni s koncepty relačních databází, rozpoznávají Join klauzuli jako INNER JOIN a Group Join klauzuli jako LEVÝ VNĚJŠÍ JOIN.

Příklady v tomto tématu ukazují několik způsobů kombinování dat pomocí Join klauzulí a Group Join klauzulí dotazu.

Vytvoření projektu a přidání ukázkových dat

Vytvoření projektu, který obsahuje ukázková data a typy

  1. Pokud chcete spustit ukázky v tomto tématu, otevřete Visual Studio a přidejte nový projekt konzolové aplikace visual basicu. Poklikejte na soubor Module1.vb vytvořený jazykem Visual Basic.

  2. Ukázky v tomto tématu používají Person typy a Pet data z následujícího příkladu kódu. Zkopírujte tento kód do výchozího Module1 modulu vytvořeného jazykem 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
    

Provedení vnitřního spojení pomocí klauzule Join

Funkce INNER JOIN kombinuje data ze dvou kolekcí. Položky, pro které se zadané hodnoty klíče shodují, jsou zahrnuty. Všechny položky z obou kolekcí, které nemají odpovídající položku v druhé kolekci, jsou vyloučeny.

V jazyce Visual Basic poskytuje LINQ dvě možnosti pro provedení INNER JOIN: implicitní spojení a explicitní spojení.

Implicitní spojení určuje kolekce, které se mají spojit v From klauzuli, a identifikuje odpovídající pole klíče v Where klauzuli. Visual Basic implicitně spojí dvě kolekce na základě zadaných polí klíče.

Explicitní spojení můžete zadat pomocí Join klauzule, pokud chcete být specifická pro pole klíče, která se mají použít ve spojení. V tomto případě Where se k filtrování výsledků dotazu dá použít klauzule.

Provedení vnitřního spojení pomocí klauzule Join

  1. Do modulu v projektu přidejte následující kód Module1 , abyste viděli příklady implicitního i explicitního vnitřního spojení.

    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
    

Provedení levého vnějšího spojení pomocí klauzule Join skupiny

LEVÉ VNĚJŠÍ SPOJENÍ zahrnuje všechny položky z levé kolekce spojení a pouze odpovídající hodnoty z pravé kolekce spojení. Z výsledku dotazu jsou vyloučeny všechny položky z pravé kolekce spojení, které nemají odpovídající položku v kolekci na levé straně.

Klauzule Group Join provádí v podstatě LEFT OUTER JOIN. Rozdíl mezi tím, co se obvykle označuje jako LEFT OUTER JOIN a jaká Group Join klauzule vrací, je, že Group Join klauzule seskupuje výsledky z pravé kolekce spojení pro každou položku v levé kolekci. V relační databázi vrátí funkce LEFT OUTER JOIN neseskupený výsledek, ve kterém každá položka ve výsledku dotazu obsahuje odpovídající položky z obou kolekcí ve spojení. V tomto případě se položky z levé kolekce spojení opakují pro každou odpovídající položku z pravé kolekce. Až dokončíte další postup, uvidíte, jak to vypadá.

Výsledky Group Join dotazu můžete načíst jako neseskupený výsledek rozšířením dotazu tak, aby vrátil položku pro každý seskupený výsledek dotazu. Abyste toho dosáhli, musíte se ujistit, že se dotazujete na DefaultIfEmpty metodu seskupené kolekce. Tím zajistíte, že položky z levé kolekce spojení budou stále zahrnuty do výsledku dotazu, i když nemají žádné odpovídající výsledky z kolekce na pravé straně. Do dotazu můžete přidat kód, který poskytne výchozí výslednou hodnotu v případě, že z kolekce spojení na pravé straně neexistuje žádná odpovídající hodnota.

Provedení levého vnějšího spojení pomocí klauzule Group Join

  1. Do modulu v projektu přidejte následující kód Module1 , abyste viděli příklady seskupených levého vnějšího spojení i neseskupených levého vnějšího spojení.

    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
    

Provedení spojení pomocí složeného klíče

Klíčové slovo v Join klauzuli nebo Group Join můžete použít And k identifikaci více polí klíčů, která se mají použít při porovnávání hodnot z připojených kolekcí. Klíčové And slovo určuje, že všechna zadaná pole klíče se musí shodovat s položkami, které se mají spojit.

Provedení spojení pomocí složeného klíče

  1. Do modulu v projektu přidejte následující kód Module1 , abyste viděli příklady spojení, které používá složený klíč.

    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
    

Spuštění kódu

Přidání kódu pro spuštění příkladů

  1. Sub Main Nahraďte modul v Module1 projektu následujícím kódem, který spustí příklady v tomto tématu.

    Sub Main()
        InnerJoinExample()
        LeftOuterJoinExample()
        CompositeKeyJoinExample()
    
        Console.ReadLine()
    End Sub
    
  2. Stisknutím klávesy F5 spusťte příklady.

Viz také