Procedura: eseguire dei join raggruppati (Guida per programmatori C#)

Il join di gruppo è utile per produrre strutture di dati gerarchiche. Abbina ogni elemento del primo insieme con un gruppo di elementi correlati del secondo insieme.

Ad esempio, una classe o una tabella del database relazionale denominata Student potrebbe contenere due campi: Id e Name. Un'altra classe o tabella del database relazionale denominata Course potrebbe contenere due campi: StudentId e CourseTitle. Un join di gruppo di queste due origini dati, basato sulla corrispondenza di Student.Id e Course.StudentId, raggrupperebbe ogni studente con un insieme di oggetti Course (che può essere vuoto).

Nota

Ogni elemento del primo insieme viene visualizzato nel gruppo di risultati di un join di gruppo indipendentemente dal fatto che gli elementi correlati vengano trovati nel secondo insieme. Nel caso in cui non venga trovato alcun elemento correlato, la sequenza di elementi correlati per tale elemento è vuota. Il selettore del risultato ha pertanto accesso a ogni elemento del primo insieme. È diverso dal selettore del risultato in un join non di gruppo, che non può accedere a elementi del primo insieme che non hanno corrispondenza nel secondo insieme.

Nel primo esempio di questo argomento viene illustrato come eseguire un join di gruppo. Nel secondo esempio viene illustrato come utilizzare un join di gruppo per creare elementi XML.

Esempio

Esempio di join di gruppo

Nell'esempio seguente viene eseguito un join di gruppo di oggetti di tipo Person e Pet basato su Person corrispondente alla proprietà Pet.Owner. Diversamente da un join non di gruppo, che produrrebbe una coppia di elementi per ogni corrispondenza, il join di gruppo produce un solo oggetto risultante per ogni elemento del primo insieme, che in questo esempio è un oggetto Person. Gli elementi corrispondenti del secondo insieme, che in questo esempio sono oggetti Pet, vengono raggruppati in un insieme. La funzione del selettore del risultato crea infine un tipo anonimo per ogni corrispondenza costituita da Person.FirstName e un insieme di oggetti 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:

Esempio di join di gruppo per la creazione di XML

I join di gruppo sono ideali per la creazione di XML tramite LINQ to XML. L'esempio seguente è analogo a quello precedente tranne per il fatto che, invece di creare tipi anonimi, la funzione del selettore del risultato crea elementi XML che rappresentano gli oggetti uniti in join. Per ulteriori informazioni su LINQ to XML, vedere 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>

Compilazione del codice

  • Creare un nuovo progetto Applicazione console in Visual Studio.

  • Aggiungere un riferimento a System.Core.dll e a System.Xml.Linq.dll se non vi è già fatto riferimento.

  • Includere gli spazi dei nomi System.Linq e System.Xml.Linq.

  • Copiare e incollare il codice dall'esempio nel file program.cs, sotto il metodo Main. Aggiungere una riga di codice al metodo Main per chiamare il metodo in cui è stata eseguita l'operazione Incolla.

  • Eseguire il programma.

Vedere anche

Attività

Procedura: eseguire degli inner join (Guida per programmatori C#)

Procedura: eseguire dei left outer join (Guida per programmatori C#)

Riferimenti

Join

GroupJoin

Tipi anonimi (Guida per programmatori C#)

Concetti

Operazioni di join

Anonymous Types

Altre risorse

LINQ to XML