Realizar operaciones de combinación externa izquierda

Una combinación externa izquierda es una combinación en la que se devuelve cada elemento de la primera colección, independientemente de si tiene elementos correlacionados en la segunda colección. Puede usar LINQ para realizar una combinación externa izquierda llamando al método DefaultIfEmpty en los resultados de una combinación agrupada.

Nota

En el ejemplo de este tema se usan las Pet clases de datos y Person de Realizar combinaciones internas.

Ejemplo

En el ejemplo siguiente se muestra cómo usar el método DefaultIfEmpty en los resultados de una combinación agrupada para realizar una combinación externa izquierda.

El primer paso para generar una combinación externa izquierda de dos colecciones consiste en realizar una combinación interna usando una combinación agrupada. (Consulte Realizar combinaciones internas para obtener una explicación de este proceso). En este ejemplo, la lista de objetos Person está combinada internamente con la lista de objetos Pet en función de un objeto Person que coincide con Pet.Owner.

El segundo paso consiste en incluir cada elemento de la primera colección (izquierda) en el conjunto de resultados, incluso cuando no haya coincidencias en la colección derecha. Esto se realiza llamando a DefaultIfEmpty en cada secuencia de elementos coincidentes de la combinación agrupada. En este ejemplo, se llama a DefaultIfEmpty en cada secuencia de objetos Pet coincidentes. El método devuelve una colección que contiene un único, valor predeterminado si la secuencia de objetos Pet coincidentes está vacía para cualquier objeto Person, con lo que cada objeto Person se representa en la colección de resultados.

Nota:

El valor predeterminado para un tipo de referencia es null; por consiguiente, el ejemplo busca una referencia NULL antes de tener acceso a cada elemento de cada colección de Pet.

Person magnus = new("Magnus", "Hedlund");
Person terry = new("Terry", "Adams");
Person charlotte = new("Charlotte", "Weiss");
Person arlene = new("Arlene", "Huff");

Pet barley = new("Barley", terry);
Pet boots = new("Boots", terry);
Pet whiskers = new("Whiskers", charlotte);
Pet bluemoon = new("Blue Moon", terry);
Pet daisy = new("Daisy", magnus);

// Create two lists.
List<Person> people = new() { magnus, terry, charlotte, arlene };
List<Pet> pets = new() { barley, boots, whiskers, bluemoon, daisy };

var query =
    from person in people
    join pet in pets on person equals pet.Owner into gj
    from subpet in gj.DefaultIfEmpty()
    select new
    {
        person.FirstName,
        PetName = subpet?.Name ?? string.Empty
    };

foreach (var v in query)
{
    Console.WriteLine($"{v.FirstName + ":",-15}{v.PetName}");
}

record class Person(string FirstName, string LastName);
record class Pet(string Name, Person Owner);

// This code produces the following output:
//
// Magnus:        Daisy
// Terry:         Barley
// Terry:         Boots
// Terry:         Blue Moon
// Charlotte:     Whiskers
// Arlene:

Vea también