Procedura: combinare dati con LINQ utilizzando join (Visual Basic)

Visual Basic fornisce le clausole di query Join e Group Join per consentire di combinare il contenuto di più raccolte in base ai valori comuni tra le raccolte. Questi valori sono noti come valori chiave. Gli sviluppatori che hanno familiarità con i concetti relativi ai database relazionali riconosceranno la clausola Join come INNER JOIN e la clausola Group Join come, LEFT OUTER JOIN.

Gli esempi in questo argomento illustrano alcuni modi per combinare i dati usando le clausole di query Join e Group Join.

Creare un progetto e aggiungere dati di esempio

Per creare un progetto contenente tipi e dati di esempio

  1. Per eseguire gli esempi in questo argomento, aprire Visual Studio e aggiungere un nuovo progetto Applicazione console Visual Basic. Fare doppio clic sul file Module1.vb creato da Visual Basic.

  2. Gli esempi in questo argomento usano i tipi Person e Pet e i dati dell'esempio di codice seguente. Copiare questo codice nel modulo Module1 predefinito creato da 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
    

Eseguire un inner join usando la clausola join

Un INNER JOIN combina i dati di due raccolte. Sono inclusi gli elementi per cui corrispondono i valori chiave specificati. Tutti gli elementi di una raccolta per cui non esiste un elemento corrispondente nell'altra raccolta vengono esclusi.

In Visual Basic LINQ offre due opzioni per l'esecuzione di un INNER JOIN: un join implicito e un join esplicito.

Un join implicito specifica le raccolte da unire in una clausola From e identifica i campi chiave corrispondenti in una clausola Where. Visual Basic unisce in modo implicito le due raccolte in base ai campi chiave specificati.

È possibile specificare un join esplicito usando la clausola Join quando si vuole essere specifici sui campi chiave da usare nel join. In questo caso, è comunque possibile usare una clausola Where per filtrare i risultati della query.

Per eseguire un inner join usando la clausola join

  1. Aggiungere il codice seguente al modulo Module1 nel progetto per visualizzare esempi di inner join implicito ed esplicito.

    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
    

Eseguire un left outer join usando la clausola Group Join

Un LEFT OUTER JOIN include tutti gli elementi della raccolta sul lato sinistro del join e solo i valori corrispondenti della raccolta sul lato destro del join. Tutti gli elementi della raccolta sul lato destro del join per cui non esiste un elemento corrispondente nella raccolta sul lato sinistro vengono esclusi dal risultato della query.

La clausola Group Join esegue, in effetti, un LEFT OUTER JOIN. La differenza tra l'operazione generalmente nota come LEFT OUTER JOIN e ciò che restituisce la clausola Group Join stanel fatto che la clausola Group Join raggruppa i risultati della raccolta sul lato destro del join per ogni elemento della raccolta sul lato sinistro. In un database relazionale, LEFT OUTER JOIN restituisce un risultato non raggruppato in cui ogni elemento nel risultato della query contiene elementi corrispondenti di entrambe le raccolte nel join. In questo caso, gli elementi della raccolta sul lato sinistro del join vengono ripetuti per ogni elemento corrispondente della raccolta sul lato destro. L'aspetto di questa operazione verrà visualizzato dopo aver completato la procedura successiva.

È possibile recuperare i risultati di una query Group Join come risultato non raggruppato estendendo la query per restituire un elemento per ogni risultato raggruppato della query. A tale scopo, è necessario assicurarsi di eseguire una query sul metodo DefaultIfEmpty della raccolta raggruppata. Ciò garantisce che gli elementi della raccolta sul lato sinistro del join siano ancora inclusi nel risultato della query anche se non sono presenti risultati corrispondenti nella raccolta sul lato destro. È possibile aggiungere codice alla query per fornire un valore di risultato predefinito quando non esiste alcun valore corrispondente nella raccolta sul lato destro del join.

Per eseguire un left outer join usando la clausola Group Join

  1. Aggiungere il codice seguente al modulo Module1 nel progetto per visualizzare esempi di un left outer join raggruppato e di un left outer join non raggruppato.

    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
    

Eseguire un join usando una chiave composta

È possibile usare la parola chiave And in una clausola Join o Group Join per identificare più campi chiave da usare per la corrispondenza dei valori delle raccolte per cui viene eseguito il join. La parola chiave And specifica che tutti i campi chiave specificati devono corrispondere per procedere al join degli elementi.

Per eseguire un join usando una chiave composta

  1. Aggiungere il codice seguente al modulo Module1 nel progetto per visualizzare esempi di un join che usa una chiave composta.

    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
    

Eseguire il codice

Per aggiungere il codice per eseguire gli esempi

  1. Sostituire la parte Sub Main nel modulo Module1 del progetto con il codice seguente per eseguire gli esempi in questo argomento.

    Sub Main()
        InnerJoinExample()
        LeftOuterJoinExample()
        CompositeKeyJoinExample()
    
        Console.ReadLine()
    End Sub
    
  2. Premere F5 per eseguire gli esempi.

Vedi anche