Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Abfrageausdrücke
Abfrageausdrücke verwenden eine deklarative Syntax, die SQL oder XQuery ähnelt, um Sammlungen abzufragen System.Collections.Generic.IEnumerable<T> . Zur Kompilierungszeit konvertiert der Compiler die Abfrageausdrücke in Methodenaufrufe zur Implementierung der Standardabfragemethoden eines LINQ-Anbieters. Anwendungen steuern die Standardabfrageoperatoren, die sich im Geltungsbereich befinden, indem sie den entsprechenden Namespace mit einer using Anweisung angeben. Der folgende Abfrageausdruck verwendet ein Array von Zeichenfolgen, gruppiert sie entsprechend dem ersten Zeichen in der Zeichenfolge und sortiert die Gruppen.
var query = from str in stringArray
group str by str[0] into stringGroup
orderby stringGroup.Key
select stringGroup;
Implizit eingegebene Variablen (var)
Sie können den Variablenmodifizierer verwenden, um den Compiler anzuweisen, den Typ zu ableiten und zuzuweisen, wie hier gezeigt:
var number = 5;
var name = "Virginia";
var query = from str in stringArray
where str[0] == 'm'
select str;
Variablen, die als var deklariert werden, sind stark typisiert, genauso wie Variablen, deren Typ Sie explizit spezifizieren. Die Verwendung var ermöglicht das Erstellen anonymer Typen, jedoch nur für lokale Variablen. Weitere Informationen finden Sie unter Implizit typierten lokalen Variablen.
Objekt- und Auflistungsinitialisierer
Objekt- und Auflistungsinitialisierer ermöglichen das Initialisieren von Objekten, ohne explizit einen Konstruktor für das Objekt aufzurufen. In der Regel verwenden Sie Initialisierer in Abfrageausdrücken, wenn sie die Quelldaten in einen neuen Datentyp projizieren. Angenommen, es gibt eine Klasse namens Customer mit den öffentlichen Eigenschaften Name und Phone, können Sie den Objektinitialisierer wie im folgenden Code verwenden:
var cust = new Customer { Name = "Mike", Phone = "555-1212" };
Wenn Sie mit Ihrer Customer Klasse fortfahren, nehmen Sie an, dass es eine Datenquelle namens IncomingOrders gibt, und dass Sie für jede Bestellung mit einer großen OrderSize eine neue Customer erstellen möchten, die auf dieser Bestellung basiert. Sie können eine LINQ-Abfrage für diese Datenquelle ausführen und die Objektinitialisierung verwenden, um eine Auflistung auszufüllen:
var newLargeOrderCustomers = from o in IncomingOrders
where o.OrderSize > 5
select new Customer { Name = o.Name, Phone = o.Phone };
Die Datenquelle hat möglicherweise mehr Eigenschaften definiert als die Customer-Klasse, wie z.B. OrderSize, aber mit der Objektinitialisierung werden die aus der Abfrage zurückgegebenen Daten in den gewünschten Datentyp umgewandelt; Sie wählen die Daten aus, die für Ihre Klasse relevant sind. Daher verfügen Sie jetzt über ein System.Collections.Generic.IEnumerable<T>-Element, das mit den neuen gewünschten Customer-Informationen gefüllt ist. Sie können auch das vorangehende Beispiel in der Methodensyntax von LINQ schreiben:
var newLargeOrderCustomers = IncomingOrders.Where(x => x.OrderSize > 5).Select(y => new Customer { Name = y.Name, Phone = y.Phone });
Ab C# 12 können Sie einen Sammlungsausdruck verwenden, um eine Auflistung zu initialisieren.
Weitere Informationen finden Sie unter:
Anonyme Typen
Der Compiler erstellt einen anonymen Typ. Nur der Compiler kann auf den Typnamen zugreifen. Anonyme Typen bieten eine bequeme Möglichkeit, einen Satz von Eigenschaften vorübergehend in einem Abfrageergebnis zu gruppieren, ohne einen separaten benannten Typ definieren zu müssen. Sie initialisieren anonyme Typen mit einem neuen Ausdruck und einem Objektinitialisierer, wie hier gezeigt:
select new {name = cust.Name, phone = cust.Phone};
Ab C# 7 können Sie Tupel verwenden, um unbenannte Typen zu erstellen.
Erweiterungsmember
Ein Erweiterungselement ist ein statisches Element einer statischen Klasse, die einem Typ zugeordnet ist, der als Empfängertyp bezeichnet wird. Sie können ein Erweiterungsmitglied aufrufen, als wäre es ein Mitglied des Empfängertyps. Mit diesem Feature können Sie neue Member zu vorhandenen Typen hinzufügen, ohne sie tatsächlich zu ändern. Die Standardabfrageoperatoren sind eine Reihe von Erweiterungsmethoden, die LINQ-Abfragefunktionen für jeden Typ bereitstellen, der IEnumerable<T> implementiert.
Lambdaausdrücke
Ein Lambda-Ausdruck ist eine Inlinefunktion, die den =>-Operator verwendet, um Eingabeparameter vom Funktionstext zu trennen, und die bei der Kompilierung in einen Delegaten oder ein Ausdrucksbaum konvertiert werden kann. Bei der LINQ-Programmierung treten Lambda-Ausdrücke auf, wenn Sie direkte Methodenaufrufe an die Standardabfrageoperatoren ausführen.
Ausdrücke als Daten
Abfrageobjekte können verfasst werden, was bedeutet, dass Sie eine Abfrage aus einer Methode zurückgeben können. Objekte, die Abfragen darstellen, speichern nicht die resultierende Auflistung, sondern die Schritte, um die Ergebnisse bei Bedarf zu erzeugen. Der Vorteil der Rückgabe von Abfrageobjekten aus Methoden besteht darin, dass Sie sie weiter verfassen oder ändern können. Daher muss jeder Rückgabewert oder out -parameter einer Methode, die eine Abfrage zurückgibt, ebenfalls diesen Typ aufweisen. Wenn eine Methode eine Abfrage in einen konkreten List<T> Oder Array Typ materialisiert, gibt sie die Abfrageergebnisse anstelle der Abfrage selbst zurück. Sie können weiterhin eine Abfragevariable erstellen oder ändern, die von einer Methode zurückgegeben wird.
Im folgenden Beispiel gibt die erste Methode QueryMethod1 eine Abfrage als Rückgabewert zurück, und die zweite Methode QueryMethod2 gibt eine Abfrage als out Parameter (returnQ im Beispiel) zurück. In beiden Fällen ist es eine abfrage, die zurückgegeben wird, nicht Abfrageergebnisse.
IEnumerable<string> QueryMethod1(int[] ints) =>
from i in ints
where i > 4
select i.ToString();
void QueryMethod2(int[] ints, out IEnumerable<string> returnQ) =>
returnQ = from i in ints
where i < 4
select i.ToString();
int[] nums = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];
var myQuery1 = QueryMethod1(nums);
Die folgende foreach Schleife führt Abfrage myQuery1 aus.
foreach (var s in myQuery1)
{
Console.WriteLine(s);
}
Positionieren Sie den Mauszeiger über myQuery1, um den Typ anzuzeigen.
Sie können die Abfrage, die direkt von QueryMethod1 zurückgegeben wird, auch ohne die Verwendung von myQuery1 ausführen.
foreach (var s in QueryMethod1(nums))
{
Console.WriteLine(s);
}
Positionieren Sie den Mauszeiger über dem Aufruf an QueryMethod1, um den Rückgabetyp anzuzeigen.
QueryMethod2 gibt eine Abfrage als Wert des out Parameters zurück:
QueryMethod2(nums, out IEnumerable<string> myQuery2);
// Execute the returned query.
foreach (var s in myQuery2)
{
Console.WriteLine(s);
}
Sie können eine Abfrage mithilfe der Abfragekomposition ändern. In diesem Fall wird das vorherige Abfrageobjekt verwendet, um ein neues Abfrageobjekt zu erstellen. Dieses neue Objekt gibt unterschiedliche Ergebnisse als das ursprüngliche Abfrageobjekt zurück.
myQuery1 = from item in myQuery1
orderby item descending
select item;
// Execute the modified query.
Console.WriteLine("\nResults of executing modified myQuery1:");
foreach (var s in myQuery1)
{
Console.WriteLine(s);
}