Grundlegende LINQ-Abfragevorgänge (C#)

Dieses Thema gibt einen kurzen Überblick über LINQ-Abfrageausdrücke und einige der geläufigsten Vorgänge, die Sie in einer Abfrage durchführen können. Ausführlichere Informationen finden Sie unter den folgenden Themen:

LINQ-Abfrageausdrücke

Standard Query Operators Overview (C#) (Übersicht über Standardabfrageoperatoren (C#))

Walkthrough: Writing Queries in C# (Exemplarische Vorgehensweise: Schreiben von Abfragen in C#)

Hinweis

Wenn Sie sich bereits mit einer Abfragesprache wie SQL oder XQuery auskennen, können Sie einen Großteil dieses Themas überspringen. Im nächsten Abschnitt erfahren Sie mehr über die from-Klausel und die Reihenfolge von Klauseln in einem LINQ-Abfrageausdruck.

Abrufen einer Datenquelle

Der erste Schritt für eine LINQ-Abfrage ist das Festlegen einer Datenquelle. Wie in den meisten Programmiersprachen muss eine Variable in C# vor ihrer Verwendung deklariert werden. In einer LINQ-Abfrage steht die from-Klausel an erster Stelle; sie führt die Datenquelle (customers) und die Bereichsvariable (cust) ein.

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

Die Bereichsvariable befindet sich wie die Iterationvariable in einer foreach-Schleife, mit dem Unterschied, dass in einem Abfrageausdruck keine Iterationen vorkommen. Wenn die Abfrage ausgeführt wird, fungiert die Bereichsvariable als Verweis auf jedes aufeinanderfolgende Element in customers. Es ist nicht notwendig, diese explizit anzugeben, da der Compiler den Typ von cust ableitet. Weitere Bereichsvariablen können mithilfe der let-Klausel eingefügt werden. Weitere Informationen finden Sie unter let-Klausel.

Hinweis

Die Bereichsvariable muss für nicht generische Datenquellen wie <xref:System.Collections.ArrayList> explizit typisiert sein. Weitere Informationen finden Sie unter Vorgehensweise: Abfragen von ArrayList mit LINQ (C#) und from-Klausel.

Filtern

Die wahrscheinlich üblichste Abfrageoperation ist das Anwenden eines Filters in Form eines booleschen Ausdrucks. Das Filtern 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. Faktisch gibt der Filter an, welche Elemente nicht in die Quellsequenz eingeschlossen werden sollen. In folgendem Beispiel werden nur die customers zurückgegeben, die eine Londoner Adresse haben.

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

Sie können die geläufigen logischen C#-Operatoren AND und OR verwenden, um so viele Filterausdrücke wie benötigt in der where-Klausel anzuwenden. Wenn Sie z.B. nur Kunden aus „London“ zurückgeben möchten, deren Name „Devon“ ist, können Sie dazu AND verwenden wie in folgendem Codebeispiel:

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

Um Kunden aus London oder Paris zurückzugeben, verwenden Sie folgenden Code:

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

Weitere Informationen finden Sie unter where-Klausel.

Sortieren

Es kann häufig praktisch sein, die zurückgegebenen Daten zu sortieren. Die orderby-Klausel sortiert die Elemente in der zurückgegebenen Sequenz anhand des Standardcomparers für den zu sortierenden Typ. Die folgende Abfrage kann z.B. so erweitert werden, dass Sie die Ergebnisse nach der Eigenschaft Name sortiert. Der Standardcomparer nimmt eine Sortierung in alphabetischer Reihenfolge (A bis Z) vor, das es sich bei Name um eine Zeichenfolge handelt.

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

Wenn Sie die Ergebnisse andersherum, von Z bis A, sortieren möchten, können Sie die orderby…descending-Klausel verwenden.

Weitere Informationen finden Sie unter orderby-Klausel.

Gruppierung

Die group-Klausel ermöglicht Ihnen, die Ergebnisse auf Grundlage eines von Ihnen angegebenen Schlüssels zu gruppieren. Sie können z.B. angeben, dass die Ergebnisse nach City gruppiert werden sollen, sodass sich alle Kunden aus London oder Paris in einer einzelnen Gruppe befinden. In diesem Fall ist cust.City der Schlüssel.

// 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 beenden, werden Ihre Ergebnisse in einer Liste aus Listen zurückgegeben. Jedes Element auf der Liste ist ein Objekt, dass über einen Key-Member und eine Liste von Elementen verfügt, die anhand dieses Schlüssels gruppiert wurden. 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 alle Member jeder Gruppe.

Wenn Sie auf die Ergebnisse eines Gruppenvorgangs verweisen müssen, könne Sie das Schlüsselwort into verwenden, um einen Bezeichner zu erstellen, der weiter abgefragt werden kann. Die folgende Abfrage gibt nur die 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.

Verknüpfen

Verknüpfungsvorgänge erstellen Verknüpfungen zwischen Sequenzen, die nicht explizit in der Datenquelle modelliert werden. Sie können z.B. eine Verknüpfung erstellen, um alle Kunden und Händler mit demselben Standort ausfindig zu machen. In LINQ arbeitet die join-Klausel immer mit Objektauflistungen statt direkt mit Datenbanktabellen.

var innerJoinQuery =
    from cust in customers
    join dist in distributors on cust.City equals dist.City
    select new { CustomerName = cust.Name, DistributorName = dist.Name };

In LINQ müssen Sie nicht join so oft wie in SQL verwenden, da Fremdschlüssel in LINQ im Objektmodell als Eigenschaften repräsentiert werden, die eine Elementauflistung enthalten. Ein Customer-Objekt enthält z.B. eine Auflistung von Order-Objekten. Sie können auf die Bestellungen zugreifen, indem Sie Punktnotation statt einer Verknüpfung verwenden:

from order in Customer.Orders...  

Weitere Informationen finden Sie unter join-Klausel.

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 z.B. bestimmen, ob Ihre Ergebnisse aus vollständigen Customer-Objekte, aus lediglich einem Member, aus einer Teilmenge von Membern oder aus einem ganz anderen Ergebnistyp, der auf einer Berechnung oder einem neu erstellten Objekt basiert, bestehen sollen. Wenn die select-Klausel etwas anderes als eine Kopie des Quellelements erzeugt, wird dieser Vorgang als Projektion bezeichnet. Das Verwenden von Projektionen zur Datentransformation ist eine leistungsfähige Funktion von LINQ-Abfrageausdrücken. Weitere Informationen finden Sie unter Datentransformationen mit LINQ (C#) und select-Klausel.

Siehe auch

Erste Schritte mit LINQ in C#
LINQ-Abfrageausdrücke
Exemplarische Vorgehensweise: Schreiben von Abfragen in C#
Abfrageschlüsselwörter (LINQ)
Anonyme Typen