Grundlegende Abfrageoperationen (LINQ)

Aktualisiert: November 2007

Dieses Thema enthält eine kurze Einführung in LINQ-Abfrageausdrücke und einige der typischen Vorgänge in einer Abfrage. Detaillierte Informationen finden Sie in folgenden Themen:

LINQ-Abfrageausdrücke (C#-Programmierhandbuch)

Übersicht über Standardabfrageoperatoren

Hinweis:

Wenn Sie bereits mit einer Abfragesprache wie SQL oder XQuery vertraut sind, können Sie den größten Teil dieses Themas überspringen. Lesen Sie die Informationen zur "from-Klausel" im nächsten Abschnitt, um mehr über die Reihenfolge von Klauseln in LINQ-Abfrageausdrücken zu erfahren.

Erhalten einer Datenquelle

In einer LINQ-Abfrage besteht der erste Schritt im Angeben der Datenquelle. In C#, wie in den meisten Programmiersprachen, muss eine Variable vor der Verwendung deklariert werden. In einer LINQ-Abfrage steht die from-Klausel zuerst, um die Datenquelle (customers) und die Bereichsvariable (cust) einzuführen.

//queryAllCustomers is an IEnumerable<Customer>
var queryAllCustomers = from cust in customers
                        select cust;

Die Bereichsvariable ist vergleichbar mit der Iterationsvariablen in einer foreach-Schleife, mit dem Unterschied, dass in einem Abfrageausdruck keine wirkliche Iteration stattfindet. Wenn die Abfrage ausgeführt wird, dient die Bereichsvariable als Verweis auf jedes darauf folgende Element in customers. Da der Compiler den Typ von cust per Rückschluss ableiten kann, müssen Sie es nicht explizit angeben. Zusätzliche Bereichsvariablen können von einer let-Klausel eingeführt werden. Weitere Informationen finden Sie unter let-Klausel (C#-Referenz).

Hinweis:

Für nicht generische Datenquellen, wie z. B. ArrayList, muss die Bereichsvariable explizit typisiert werden. Weitere Informationen finden Sie unter Gewusst wie: Abfragen von ArrayList mit LINQ und unter from-Klausel (C#-Referenz).

Filtern

Die wahrscheinlich üblichste Abfrageoperation ist das Anwenden eines Filters in Form eines booleschen Ausdrucks. Der Filter bewirkt, dass die Abfrage nur jene Elemente zurückgibt, für die der Ausdruck den Wert true hat. Das Ergebnis wird durch Verwendung der where-Klausel erzeugt. Der aktive Filter gibt an, welche Elemente aus der Quellsequenz ausgeschlossen werden sollen. Im folgenden Beispiel werden nur jene customers zurückgegeben, die eine Adresse in London aufweisen.

var queryLondonCustomers = from cust in customers
                           where cust.City == "London"
                           select cust;

Sie können die bekannten logischen C#-Operatoren AND und OR verwenden, um so viele Filterausdrücke wie möglich in der where-Klausel anzuwenden. Um beispielsweise nur die Kunden zurückzugeben, die aus "London" stammen und (AND) den Namen "Devon" haben, verwenden Sie folgenden Code:

where cust.City=="London" && cust.Name == "Devon"

Um Kunden aus London oder Paris zurückzugeben, würden Sie folgenden Code schreiben:

where cust.City == "London" || cust.City == "Paris"

Weitere Informationen finden Sie unter where-Klausel (C#-Referenz).

Sortierung

Oft ist es hilfreich, die zurückgegebenen Daten zu sortieren. Mit der orderby-Klausel können die Elemente in der zurückgegebenen Sequenz anhand des Standardvergleichs für den zu sortierenden Typ sortiert werden. Zum Beispiel kann die folgende Abfrage erweitert werden, um die Ergebnisse auf Grundlage der Name-Eigenschaft zu sortieren. Da Name eine Zeichenfolge ist, führt der Standardvergleich eine alphabetische Sortierung von A bis Z aus.

var queryLondonCustomers3 = 
    from cust in customers
    where cust.City == "London"
    orderby cust.Name ascending
    select cust;

Um die Ergebnisse in umgekehrter Reihenfolge zu sortieren (von Z bis A), verwenden Sie die orderby…descending-Klausel.

Weitere Informationen finden Sie unter orderby-Klausel (C#-Referenz).

Gruppierung

Die group-Klausel ermöglicht Ihnen, die Ergebnisse auf Grundlage eines Schlüssels zu gruppieren, den Sie angeben. Sie können beispielsweise angeben, dass die Ergebnisse anhand von City sortiert werden, sodass sich alle Kunden aus London oder Paris in einzelnen Gruppen befinden. In diesem Beispiel ist cust.City der Schlüssel.

Hinweis:

Die Typen sind in den folgenden Beispielen explizit, um das Konzept zu illustrieren. Sie können auch die implizite Typisierung für custQuery, group und customer verwenden, sodass der Compiler den genauen Typ bestimmt.

// queryCustomersByCity is an IEnumerable<IGrouping<string, Customer>>
  var queryCustomersByCity =
      from cust in customers
      group cust by cust.City;

  // customerGroup is an IGrouping<string, Customer>
  foreach (var customerGroup in queryCustomersByCity)
  {
      Console.WriteLine(customerGroup.Key);
      foreach (Customer customer in customerGroup)
      {
          Console.WriteLine("    {0}", customer.Name);
      }
  }

Wenn Sie eine Abfrage mit einer group-Klausel abschließen, haben die Ergebnisse die Form einer Liste mit Listen. Jedes Element in der Liste ist ein Objekt, das einen Key-Member und eine Elementliste aufweist, die unter diesem Schlüssel gruppiert werden. Wenn Sie eine Abfrage durchlaufen, die eine Sequenz von Gruppen erzeugt, müssen Sie eine geschachtelte foreach-Schleife verwenden. Die äußere Schleife durchläuft jede Gruppe, und die innere Schleife durchläuft die Member jeder Gruppe.

Wenn Sie auf die Ergebnisse einer Gruppenoperation verweisen müssen, können Sie das into-Schlüsselwort zum Erstellen eines Bezeichners verwenden, der weitergehend abgefragt werden kann. Die folgende Abfrage gibt nur jene Gruppen zurück, die mehr als zwei Kunden enthalten:

// custQuery is an IEnumerable<IGrouping<string, Customer>>
var custQuery =
    from cust in customers
    group cust by cust.City into custGroup
    where custGroup.Count() > 2
    orderby custGroup.Key
    select custGroup;

Weitere Informationen finden Sie unter group-Klausel (C#-Referenz).

Verknüpfen

Verknüpfungsoperationen erstellen Zuordnungen zwischen Sequenzen, die nicht explizit in den Datenquellen modelliert werden. Sie können beispielsweise eine Verknüpfung durchführen, um alle Kunden in London zu finden, die Produkte von Anbietern in Paris bestellen. In LINQ wird die join-Klausel immer für Objektauflistungen anstatt für Datenbanktabellen ausgeführt. In LINQ müssen Sie join nicht so häufig verwenden wie in SQL, da die Fremdschlüssel in LINQ im Objektmodell als Eigenschaften dargestellt werden, die eine Elementauflistung enthalten. Zum Beispiel enthält ein Customer-Objekt eine Auflistung von Order-Objekten. Statt eine Verknüpfung auszuführen, greifen Sie auf die Reihenfolgen mit der Punktnotation zu:

from order in Customer.Orders...

Weitere Informationen finden Sie unter join-Klausel (C#-Referenz).

Auswählen (Projektionen)

Die select-Klausel erzeugt die Ergebnisse der Abfrage und gibt die "Form" oder den Typ jedes zurückgegebenen Elements an. Sie können beispielsweise angeben, ob Ihre Ergebnisse aus vollständigen Customer-Objekten, nur einem Member, einer Teilmenge von Membern oder einem ganz anderen Ergebnistyp, der auf einer Berechnung oder einer neuen Objekterstellung basiert, bestehen soll. Wenn die select-Klausel ein anderes Ergebnis als eine Kopie des Quellelements zurückgibt, wird der Vorgang als Projektion bezeichnet. Die Verwendung von Projektionen für die Datentransformation ist ein leistungsstarkes Merkmal von LINQ-Abfrageausdrücken. Weitere Informationen finden Sie unter Datentransformationen mit LINQ und unter select-Klausel (C#-Referenz).

Siehe auch

Konzepte

LINQ-Abfrageausdrücke (C#-Programmierhandbuch)

Referenz

Anonyme Typen (C#-Programmierhandbuch)

Weitere Ressourcen

Erste Schritte mit LINQ in C#

Abfrageschlüsselwörter (C#-Referenz)