Cómo: Realizar combinaciones agrupadas (Guía de programación de C#)
Actualización: noviembre 2007
La combinación agrupada es útil para generar estructuras de datos jerárquicas. Empareja cada elemento de la primera colección con un conjunto de elementos correlacionados de la segunda colección.
Por ejemplo, una clase o una tabla de base de datos relacional denominada Student podría contener dos campos: Id y Name. Una segunda clase o tabla de base de datos relacional denominada Course podría contener dos campos: StudentId y CourseTitle. Una combinación agrupada de estos dos orígenes de datos, basada en la coincidencia de Student.Id y Course.StudentId, agruparía cada elemento de Student con una colección de objetos de Course (que podría estar vacía).
Nota: |
---|
Cada elemento de la primera colección aparece en el conjunto de resultados de una combinación agrupada, independientemente de si se encuentran elementos correlacionados en la segunda colección. En caso de que no se encuentren elementos que puedan correlacionarse, la secuencia de elementos correlacionados para ese elemento está vacía. El selector de resultados tiene acceso a cada elemento de la primera colección. Esto se diferencia de una combinación no agrupada, donde el selector de resultados no puede tener acceso a elementos de la primera colección que no tengan ninguna coincidencia en la segunda colección. |
En el primer ejemplo de este tema se muestra cómo realizar una combinación agrupada. En el segundo ejemplo se muestra cómo utilizar una combinación agrupada para crear elementos XML.
Ejemplo
Ejemplo de combinación agrupada
https://go.microsoft.com/fwlink/?LinkId=44293 En el ejemplo siguiente se realiza una combinación agrupada de objetos de tipo Person y Pet basada en elementos Person que coinciden con la propiedad Pet.Owner. A diferencia de una combinación no agrupada, que generaría un par de elementos para cada coincidencia, la combinación agrupada sólo genera un objeto resultante para cada elemento de la primera colección, que en este ejemplo es un objeto Person. Los elementos correspondientes de la segunda colección, que en este ejemplo son objetos Pet, se agrupan en una colección. Finalmente, la función de selector de resultados crea un tipo anónimo para cada coincidencia formada por Person.FirstName y una colección de objetos Pet.
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}
/// <summary>
/// This example performs a grouped join.
/// </summary>
public static void GroupJoinExample()
{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };
Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };
// Create two lists.
List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };
// Create a list where each element is an anonymous type
// that contains the person's first name and a collection of
// pets that are owned by them.
var query = from person in people
join pet in pets on person equals pet.Owner into gj
select new { OwnerName = person.FirstName, Pets = gj };
foreach (var v in query)
{
// Output the owner's name.
Console.WriteLine("{0}:", v.OwnerName);
// Output each of the owner's pet's names.
foreach (Pet pet in v.Pets)
Console.WriteLine(" {0}", pet.Name);
}
}
// This code produces the following output:
//
// Magnus:
// Daisy
// Terry:
// Barley
// Boots
// Blue Moon
// Charlotte:
// Whiskers
// Arlene:
Ejemplo de combinación agrupada para crear XML
Las combinaciones agrupadas son ideales para crear XML utilizando LINQ to XML. El ejemplo siguiente es similar al anterior, salvo que en lugar de crear tipos anónimos, la función de selector de resultados crea elementos XML que representan los objetos combinados. Para obtener más información acerca de LINQ to XML, vea LINQ to XML.
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
class Pet
{
public string Name { get; set; }
public Person Owner { get; set; }
}
/// <summary>
/// This example creates XML output from a grouped join.
/// </summary>
public static void GroupJoinXMLExample()
{
Person magnus = new Person { FirstName = "Magnus", LastName = "Hedlund" };
Person terry = new Person { FirstName = "Terry", LastName = "Adams" };
Person charlotte = new Person { FirstName = "Charlotte", LastName = "Weiss" };
Person arlene = new Person { FirstName = "Arlene", LastName = "Huff" };
Pet barley = new Pet { Name = "Barley", Owner = terry };
Pet boots = new Pet { Name = "Boots", Owner = terry };
Pet whiskers = new Pet { Name = "Whiskers", Owner = charlotte };
Pet bluemoon = new Pet { Name = "Blue Moon", Owner = terry };
Pet daisy = new Pet { Name = "Daisy", Owner = magnus };
// Create two lists.
List<Person> people = new List<Person> { magnus, terry, charlotte, arlene };
List<Pet> pets = new List<Pet> { barley, boots, whiskers, bluemoon, daisy };
// Create XML to display the hierarchical organization of people and their pets.
XElement ownersAndPets = new XElement("PetOwners",
from person in people
join pet in pets on person equals pet.Owner into gj
select new XElement("Person",
new XAttribute("FirstName", person.FirstName),
new XAttribute("LastName", person.LastName),
from subpet in gj
select new XElement("Pet", subpet.Name)));
Console.WriteLine(ownersAndPets);
}
// This code produces the following output:
//
// <PetOwners>
// <Person FirstName="Magnus" LastName="Hedlund">
// <Pet>Daisy</Pet>
// </Person>
// <Person FirstName="Terry" LastName="Adams">
// <Pet>Barley</Pet>
// <Pet>Boots</Pet>
// <Pet>Blue Moon</Pet>
// </Person>
// <Person FirstName="Charlotte" LastName="Weiss">
// <Pet>Whiskers</Pet>
// </Person>
// <Person FirstName="Arlene" LastName="Huff" />
// </PetOwners>
Compilar el código
Cree un nuevo proyecto de Aplicación de consola en Visual Studio.
Agregue una referencia a System.Core.dll y a System.Xml.Linq.dll si ésta no existe aún.
Incluya los espacios de nombres System.Linq y System.Xml.Linq.
Copie el código del ejemplo y péguelo en el archivo program.cs , bajo el método Main. Agregue una línea de código al método Main para llamar al método que pegó.
Ejecute el programa.
Vea también
Tareas
Cómo: Realizar combinaciones internas (Guía de programación de C#)
Cómo: Realizar operaciones de combinación externa izquierda (Guía de programación de C#)
Conceptos
Referencia
Tipos anónimos (Guía de programación de C#)