Gewusst wie: Ausführen innerer Verknüpfungen (C#-Programmierhandbuch)

Aktualisiert: November 2007

Bei relationalen Datenbanken erstellt eine innere Verknüpfung einen Ergebnissatz, in dem jedes Element der ersten Auflistung einmal für jedes übereinstimmende Element in der zweiten Auflistung angezeigt wird. Wenn ein Element in der ersten Auflistung keine übereinstimmenden Elemente hat, wird es nicht im Ergebnissatz angezeigt. Die Join-Methode, die von der join-Klausel in C# oder der Join-Klausel in Visual Basic aufgerufen wird, implementiert eine innere Verknüpfung.

Dieses Thema zeigt vier Variationen, wie Sie eine innere Verknüpfung ausführen können:

  • Eine einfache innere Verknüpfung, die Elemente aus zwei Datenquellen anhand eines einfachen Schlüssels verknüpft.

  • Eine innere Verknüpfung, die Elemente aus zwei Datenquellen anhand eines zusammengesetzten Schlüssels verknüpft. Ein zusammengesetzter Schlüssel besteht aus mehr als einem Wert und ermöglicht es Ihnen, Elemente anhand mehr als einer Eigenschaft zu verknüpfen.

  • Eine Mehrfachverknüpfung, in der aufeinander folgende Verknüpfungsoperationen aneinander angefügt werden.

  • Eine innere Verknüpfung, die durch eine Gruppenverknüpfung implementiert wird.

Beispiel

Beispiel für einfache Schlüsselverknüpfung

Im folgenden Beispiel werden zwei Auflistungen erstellt, die Objekte von zwei benutzerdefinierten Typen, Person und Pet, enthalten. Die Abfrage verwendet die join-Klausel in C# oder die Join-Klausel in Visual Basic, um die Person-Objekte an die Pet-Objekte anzupassen, deren Owner diese Person ist. Mit der select-Klausel in C# oder der Select-Klausel in Visual Basic wird die Darstellung der erstellten Objekte definiert. In diesem Beispiel handelt es sich bei den erstellten Objekten um anonyme Typen, die aus dem Vornamen des Besitzers und dem Namen des Tiers bestehen.

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>
/// Simple inner join.
/// </summary>
public static void InnerJoinExample()
{
    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" };
    Person rui = new Person { FirstName = "Rui", LastName = "Raposo" };

    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 = rui };
    Pet daisy = new Pet { Name = "Daisy", Owner = magnus };

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

    // Create a collection of person-pet pairs. Each element in the collection
    // is an anonymous type containing both the person's name and their pet's name.
    var query = from person in people
                join pet in pets on person equals pet.Owner
                select new { OwnerName = person.FirstName, PetName = pet.Name };

    foreach (var ownerAndPet in query)
    {
        Console.WriteLine("\"{0}\" is owned by {1}", ownerAndPet.PetName, ownerAndPet.OwnerName);
    }
}

// This code produces the following output:
//
// "Daisy" is owned by Magnus
// "Barley" is owned by Terry
// "Boots" is owned by Terry
// "Whiskers" is owned by Charlotte
// "Blue Moon" is owned by Rui

Beachten Sie, dass das Person-Objekt, dessen LastName "Huff" ist, nicht im Ergebnissatz angezeigt wird, da es kein Pet-Objekt gibt, bei dem Pet.Owner dieser Person entspricht.

Beispiel für zusammengesetzte Schlüsselverknüpfung

Anstatt Elemente anhand nur einer Eigenschaft zu verknüpfen, können Sie mit einem zusammengesetzten Schlüssel Elemente anhand mehrerer Eigenschaften vergleichen. Geben Sie dazu die Schlüsselauswahlfunktion für jede Auflistung an, um einen anonymen Typ zurückzugeben, der aus den Eigenschaften besteht, die Sie vergleichen möchten. Wenn Sie die Eigenschaften beschriften, müssen sie die gleiche Bezeichnung im anonymen Typ jedes Schlüssels haben. Die Eigenschaften müssen auch in der gleichen Reihenfolge angezeigt werden.

Im folgenden Beispiel wird mit einer Liste von Employee-Objekten und einer Liste von Student-Objekten festgelegt, welche Angestellten ebenfalls Studenten sind. Beide Typen verfügen über eine FirstName-Eigenschaft und eine LastName-Eigenschaft des Typs String. Die Funktionen, mit denen die zusammengesetzten Schlüssel aus den Elementen jeder Liste erstellt werden, geben einen anonymen Typ zurück, der aus der FirstName-Eigenschaft und der LastName-Eigenschaft jedes Elements besteht. Die Verknüpfungsoperation vergleicht diese zusammengesetzten Schlüssel auf Gleichheit und gibt Objektpaare aus jeder Liste zurück, wenn der Vor- und Nachname übereinstimmen.

class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int EmployeeID { get; set; }
}

class Student
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int StudentID { get; set; }
}

/// <summary>
/// Performs a join operation using a composite key.
/// </summary>
public static void CompositeKeyJoinExample()
{
    // Create a list of employees.
    List<Employee> employees = new List<Employee> {
        new Employee { FirstName = "Terry", LastName = "Adams", EmployeeID = 522459 },
         new Employee { FirstName = "Charlotte", LastName = "Weiss", EmployeeID = 204467 },
         new Employee { FirstName = "Magnus", LastName = "Hedland", EmployeeID = 866200 },
         new Employee { FirstName = "Vernette", LastName = "Price", EmployeeID = 437139 } };

    // Create a list of students.
    List<Student> students = new List<Student> {
        new Student { FirstName = "Vernette", LastName = "Price", StudentID = 9562 },
        new Student { FirstName = "Terry", LastName = "Earls", StudentID = 9870 },
        new Student { FirstName = "Terry", LastName = "Adams", StudentID = 9913 } };

    // Join the two data sources based on a composite key consisting of first and last name,
    // to determine which employees are also students.
    IEnumerable<string> query = from employee in employees
                                join student in students
                                on new { employee.FirstName, employee.LastName }
                                equals new { student.FirstName, student.LastName }
                                select employee.FirstName + " " + employee.LastName;

    Console.WriteLine("The following people are both employees and students:");
    foreach (string name in query)
        Console.WriteLine(name);
}

// This code produces the following output:
//
// The following people are both employees and students:
// Terry Adams
// Vernette Price

Beispiel für Mehrfachverknüpfung

Jede beliebige Anzahl von Verknüpfungsoperationen kann aneinander angefügt werden, um eine Mehrfachverknüpfung durchzuführen. Jede join-Klausel in C# oder Join-Klausel in Visual Basic verknüpft eine angegebene Datenquelle mit den Ergebnissen der vorherigen Verknüpfung.

Im folgenden Beispiel werden drei Auflistungen erstellt: eine Liste mit Person-Objekten, eine Liste mit Cat-Objekten und eine mit Dog-Objekten.

Die erste join-Klausel in C# oder die Join-Klausel in Visual Basic gleicht Personen und Katzen anhand eines Person-Objekts, das Cat.Owner entspricht, aneinander an. Es wird eine Sequenz anonymer Typen zurückgegeben, die das Person-Objekt und Cat.Name enthält.

Die zweite join-Klausel in C# oder die Join-Klausel in Visual Basic verknüpft die anonymen Typen, die von der ersten Verknüpfung mit Dog-Objekten in der angegebenen Liste mit Hunden zurückgegeben wurden, anhand eines zusammengesetzten Schlüssels, der aus der Owner-Eigenschaft des Typs Person und dem ersten Buchstaben des Tiernamens besteht. Es wird eine Sequenz anonymer Typen zurückgegeben, die die Cat.Name-Eigenschaft und die Dog.Name-Eigenschaft jedes übereinstimmenden Paars enthält. Da es sich hierbei um eine innere Verknüpfung handelt, werden nur die Objekte aus der ersten Datenquelle, für die es eine Übereinstimmung in der zweiten Datenquelle gibt, zurückgegeben.

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

class Pet
{
    public string Name { get; set; }
    public Person Owner { get; set; }
}

class Cat : Pet
{ }

class Dog : Pet
{ }

public static void MultipleJoinExample()
{
    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" };
    Person rui = new Person { FirstName = "Rui", LastName = "Raposo" };
    Person phyllis = new Person { FirstName = "Phyllis", LastName = "Harris" };

    Cat barley = new Cat { Name = "Barley", Owner = terry };
    Cat boots = new Cat { Name = "Boots", Owner = terry };
    Cat whiskers = new Cat { Name = "Whiskers", Owner = charlotte };
    Cat bluemoon = new Cat { Name = "Blue Moon", Owner = rui };
    Cat daisy = new Cat { Name = "Daisy", Owner = magnus };

    Dog fourwheeldrive = new Dog { Name = "Four Wheel Drive", Owner = phyllis };
    Dog duke = new Dog { Name = "Duke", Owner = magnus };
    Dog denim = new Dog { Name = "Denim", Owner = terry };
    Dog wiley = new Dog { Name = "Wiley", Owner = charlotte };
    Dog snoopy = new Dog { Name = "Snoopy", Owner = rui };
    Dog snickers = new Dog { Name = "Snickers", Owner = arlene };

    // Create three lists.
    List<Person> people =
        new List<Person> { magnus, terry, charlotte, arlene, rui, phyllis };
    List<Cat> cats =
        new List<Cat> { barley, boots, whiskers, bluemoon, daisy };
    List<Dog> dogs =
        new List<Dog> { fourwheeldrive, duke, denim, wiley, snoopy, snickers };

    // The first join matches Person and Cat.Owner from the list of people and
    // cats, based on a common Person. The second join matches dogs whose names start
    // with the same letter as the cats that have the same owner.
    var query = from person in people
                join cat in cats on person equals cat.Owner
                join dog in dogs on 
                new { Owner = person, Letter = cat.Name.Substring(0, 1) }
                equals new { dog.Owner, Letter = dog.Name.Substring(0, 1) }
                select new { CatName = cat.Name, DogName = dog.Name };

    foreach (var obj in query)
    {
        Console.WriteLine(
            "The cat \"{0}\" shares a house, and the first letter of their name, with \"{1}\".", 
            obj.CatName, obj.DogName);
    }
}

// This code produces the following output:
//
// The cat "Daisy" shares a house, and the first letter of their name, with "Duke".
// The cat "Whiskers" shares a house, and the first letter of their name, with "Wiley".

Innere Verknüpfung mithilfe des Beispiels für gruppierte Verknüpfungen

Im folgenden Beispiel wird gezeigt, wie Sie eine innere Verknüpfung implementieren können, indem Sie eine Gruppenverknüpfung verwenden.

In query1 ist die Liste der Person-Objekte über eine Gruppenverknüpfung mit der Liste der Pet-Objekte verknüpft, wobei die Person mit der Pet.Owner-Eigenschaft übereinstimmt. Die Gruppenverknüpfung erstellt eine Auflistung von Zwischengruppen, wobei jede Gruppe aus einem Person-Objekt und einer Sequenz übereinstimmender Pet-Objekte besteht.

Durch das Hinzufügen einer zweiten from-Klausel (From-Klausel in Visual Basic) zur Abfrage, wird diese Sequenz mit Sequenzen zu einer längeren Sequenz zusammengefasst (vereinfacht). Der Typ der Elemente der letzten Sequenz wird durch die select-Klausel (die Select-Klausel in Visual Basic) angegeben. In diesem Beispiel ist der Typ ein anonymer Typ, der aus der Person.FirstName-Eigenschaft und der Pet.Name-Eigenschaft für jedes übereinstimmende Paar besteht.

Das Ergebnis von query1 entspricht dem Ergebnissatz, der durch den Einsatz der join-Klausel ohne die into-Klausel in C#, oder der Join-Klausel in Visual Basic erzielt worden wäre, um eine innere Verknüpfung auszuführen. Die query2-Variable veranschaulicht diese entsprechende Abfrage.

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>
/// Performs an inner join by using GroupJoin().
/// </summary>
public static void InnerGroupJoinExample()
{
    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 };

    var query1 = from person in people
                 join pet in pets on person equals pet.Owner into gj
                 from subpet in gj
                 select new { OwnerName = person.FirstName, PetName = subpet.Name };

    Console.WriteLine("Inner join using GroupJoin():");
    foreach (var v in query1)
    {
        Console.WriteLine("{0} - {1}", v.OwnerName, v.PetName);
    }

    var query2 = from person in people
                 join pet in pets on person equals pet.Owner
                 select new { OwnerName = person.FirstName, PetName = pet.Name };

    Console.WriteLine("\nThe equivalent operation using Join():");
    foreach (var v in query2)
        Console.WriteLine("{0} - {1}", v.OwnerName, v.PetName);
}

// This code produces the following output:
//
// Inner join using GroupJoin():
// Magnus - Daisy
// Terry - Barley
// Terry - Boots
// Terry - Blue Moon
// Charlotte - Whiskers
//
// The equivalent operation using Join():
// Magnus - Daisy
// Terry - Barley
// Terry - Boots
// Terry - Blue Moon
// Charlotte - Whiskers

Kompilieren des Codes

  • Erstellen Sie ein neues Konsolenanwendungsprojekt in Visual Studio.

  • Fügen Sie einen Verweis auf System.Core.dll hinzu, wenn er noch nicht existiert.

  • Schließen Sie den System.Linq-Namespace ein.

  • Kopieren Sie den Code aus dem Beispiel, und fügen Sie ihn in die program.cs-Datei unter der Main-Methode ein. Fügen Sie der Main-Methode eine Codezeile hinzu, um die eingefügte Methode aufzurufen.

  • Führen Sie das Programm aus.

Siehe auch

Aufgaben

Gewusst wie: Ausführen von Gruppenverknüpfungen (C#-Programmierhandbuch)

Gewusst wie: Ausführen linker äußerer Verknüpfungrn (C#-Programmierhandbuch)

Konzepte

Verknüpfungsvorgänge

Anonyme Typen

Referenz

Join

GroupJoin

Anonyme Typen (C#-Programmierhandbuch)