Cómo: Combinar datos con LINQ usando cláusulas Join (Visual Basic)

Actualización: noviembre 2007

Visual Basic proporciona las cláusulas de consulta Group Join y Join para permitir combinar el contenido de varias colecciones basándose en valores comunes entre colecciones. Estos valores se conocen como valores de clave. Los programadores familiarizados con conceptos de bases de datos relacionales reconocerán la cláusula Join como INNER JOIN y la cláusula Group Join como LEFT OUTER JOIN.

Los ejemplos de este tema muestran una cuantas formas de combinar datos utilizando las cláusulas de consulta Group Join y Join.

Crear un proyecto y agregar datos de ejemplo

Para crear un proyecto que contiene datos y tipos de ejemplo

  1. Para ejecutar los ejemplos de este tema, abra Visual Studio y agregue un nuevo proyecto de aplicación de consola de Visual Basic. Haga doble clic en el archivo Module1.vb creado por Visual Basic.

  2. Los ejemplos de este tema usan los tipos Person y Pet, así como los datos del siguiente ejemplo de código. Copie este código en el módulo Module1 predeterminado creado por 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 _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
    

Realizar una combinación interna mediante la cláusula Join

Una combinación INNER JOIN combina los datos de dos colecciones. Los elementos para los que se incluye la coincidencia de los valores clave especificados. Se excluye cualquier elemento de cualquier colección que no tenga ningún elemento coincidente en la otra colección.

En Visual Basic, LINQ proporciona dos opciones para realizar una combinación INNER JOIN: una combinación implícita y una explícita.

Una combinación implícita especifica las colecciones que se van a combinar en una cláusula From e identifica los campos clave coincidentes de una cláusula Where. Visual Basic combina implícitamente las dos colecciones basándose en los campos clave especificados.

Puede especificar una combinación explícita utilizando la cláusula Join cuando desee ser concreto sobre los campos clave que se van a usar en la combinación. En este caso, una cláusula Where se puede seguir usando para filtrar los resultados de la consulta.

Para realizar una combinación interna mediante la cláusula Join

  • Agregue el código siguiente al módulo Module1 del proyecto para ver ejemplos de una combinación interna tanto implícita como explícita.

    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
    

Realizar una combinación externa izquierda mediante la cláusula Group Join

Una combinación LEFT OUTER JOIN incluye todos los elementos de la colección de la izquierda de la combinación y sólo los valores coincidentes de la colección de la derecha de la combinación. Cualquier elemento de la colección de la derecha de la combinación que no tiene ningún elemento coincidente en la colección de la izquierda se excluye del resultado de la consulta.

La cláusula Group Join realiza, de hecho, una combinación LEFT OUTER JOIN. La diferencia entre lo que normalmente se conoce como LEFT OUTER JOIN y lo que devuelve la cláusula Group Join es que la cláusula Group Join agrupa los resultados de la colección de la derecha de la combinación de cada elemento de la colección de la izquierda. En una base de datos relacional, una combinación LEFT OUTER JOIN devuelve un resultado desagrupado en el que cada elemento del resultado de la consulta contiene los elementos coincidentes de ambas colecciones de la combinación. En este caso, los elementos de la colección de la izquierda de la combinación se repiten por cada elemento coincidente de la colección de la derecha. Verá el aspecto cuando complete el procedimiento siguiente.

Puede recuperar los resultados de una consulta Group Join como resultado desagrupado ampliando la consulta para devolver un elemento por cada resultado de la consulta agrupado. Para ello, debe asegurarse de que realiza la consulta en el método DefaultIfEmpty de la colección agrupada. De esta forma, se asegura de que los elementos de la colección de la izquierda de la combinación siguen estando incluidos en el resultado de la consulta aunque no tengan ningún resultado coincidente en la colección de la derecha. Puede agregar código a la consulta para proporcionar un valor de resultado predeterminado cuando no haya ningún valor coincidente en la colección de la derecha de la combinación.

Para realizar una combinación externa izquierda mediante la cláusula Group Join

  • Agregue el código siguiente al módulo Module1 del proyecto para ver ejemplos tanto de una combinación externa izquierda agrupada como de una combinación externa izquierda desagrupada.

    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:     
    

Realizar una combinación mediante una clave compuesta

Puede utilizar la palabra clave And en la cláusula Join o Group Join para identificar varios campos clave que se van a usar cuando se combinen los valores coincidentes de las colecciones. La palabra clave And especifica que todos los campos clave especificados deben coincidir con los elementos que se van a combinar.

Para realizar una combinación mediante una clave compuesta

  • Agregue el código siguiente al módulo Module1 del proyecto para ver ejemplos de una combinación que usa una clave compuesta.

    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
    

Ejecutar el código

Para agregar código con el fin de ejecutar los ejemplos

  1. Reemplace Sub Main en el módulo Module1 del proyecto por el código siguiente para ejecutar los ejemplos de este tema.

    Sub Main()
      InnerJoinExample()
      LeftOuterJoinExample()
      CompositeKeyJoinExample()
    
      Console.ReadLine()
    End Sub
    
  2. Presione F5 para ejecutar los ejemplos.

Vea también

Conceptos

Introducción a LINQ en Visual Basic

Referencia

Join (Cláusula, Visual Basic)

Group Join (Cláusula, Visual Basic)

From (Cláusula, Visual Basic)

Where (Cláusula, Visual Basic)

Otros recursos

LINQ en Visual Basic

Consultas (Visual Basic)