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.
Um Abfragen effektiv zu schreiben, sollten Sie verstehen, wie sich die Typen der Variablen in einem vollständigen Abfragevorgang miteinander in Beziehung setzen. Wenn Sie diese Beziehungen verstehen, verstehen Sie die LINQ-Beispiele und Codebeispiele in der Dokumentation einfacher. Darüber hinaus werden Sie verstehen, was geschieht, wenn Variablen durch die Verwendung von var
implizit typisiert werden.
LINQ-Abfrageoperationen sind in der Datenquelle, in der Abfrage selbst und in der Abfrageausführung stark typisiert. Der Typ der Variablen in der Abfrage muss mit dem Typ der Elemente in der Datenquelle und mit dem Typ der Iterationsvariablen in der foreach
Anweisung kompatibel sein. Diese starke Eingabe garantiert, dass Typfehler zur Kompilierzeit abgefangen werden, wenn sie korrigiert werden können, bevor benutzer auf sie stoßen.
Um diese Typbeziehungen zu veranschaulichen, verwenden die meisten der folgenden Beispiele eine explizite Typisierung für alle Variablen. Das letzte Beispiel zeigt, wie die gleichen Prinzipien angewendet werden, auch wenn Sie mit impliziter Typisierung mithilfe von var
arbeiten.
Abfragen, die die Quelldaten nicht transformieren
Die folgende Abbildung zeigt einen LINQ to Objects-Abfragevorgang, der keine Transformationen für die Daten ausführt. Die Quelle enthält eine Abfolge von Zeichenfolgen, und die Abfrageausgabe ist auch eine Abfolge von Zeichenfolgen.
- Das Typargument der Datenquelle bestimmt den Typ der Bereichsvariable.
- Der Typ des ausgewählten Objekts bestimmt den Typ der Abfragevariable. Hier
name
ist eine Zeichenfolge. Daher ist die Abfragevariable eineIEnumerable<string>
. - Die Abfragevariable durchläuft in der
foreach
-Anweisung verschiedene Iterationen. Da es sich bei der Abfragevariable um eine Abfolge von Zeichenfolgen handelt, ist die Iterationsvariable auch eine Zeichenfolge.
Abfragen, die die Quelldaten transformieren
Die folgende Abbildung zeigt einen LINQ to SQL-Abfragevorgang, der eine einfache Transformation der Daten durchführt. Die Abfrage akzeptiert eine Abfolge von Customer
Objekten als Eingabe und wählt nur die Name
Eigenschaft im Ergebnis aus. Da Name
es sich um eine Zeichenfolge handelt, erzeugt die Abfrage eine Abfolge von Zeichenfolgen als Ausgabe.
- Das Typargument der Datenquelle bestimmt den Typ der Bereichsvariable.
- Die
select
Anweisung gibt dieName
Eigenschaft anstelle des vollständigenCustomer
Objekts zurück. DaName
eine Zeichenfolge ist, ist das Typargument voncustNameQuery
string
, nichtCustomer
. - Da
custNameQuery
es sich um eine Abfolge von Zeichenfolgen handelt, muss die Iterationsvariable derforeach
Schleife auch einestring
sein.
Die folgende Abbildung zeigt eine etwas komplexere Transformation. Die select
Anweisung gibt einen anonymen Typ zurück, der nur zwei Member des ursprünglichen Customer
Objekts erfasst.
- Das Typargument der Datenquelle ist immer der Typ der Bereichsvariable in der Abfrage.
- Da die
select
Anweisung einen anonymen Typ erzeugt, muss die Abfragevariable implizit mithilfe vonvar
typisiert werden. - Da der Typ der Abfragevariable implizit ist, muss die Iterationsvariable in der
foreach
Schleife ebenfalls implizit sein.
Dem Compiler erlauben, Typinformationen abzuleiten.
Obwohl Sie die Typbeziehungen in einem Abfragevorgang verstehen sollten, haben Sie die Möglichkeit, dem Compiler die gesamte Arbeit für Sie zu ermöglichen. Das var-Schlüsselwort kann für jede lokale Variable in einem Abfragevorgang verwendet werden. Die folgende Abbildung ähnelt beispielnummer 2, die zuvor erläutert wurde. Der Compiler stellt jedoch den starken Typ für jede Variable im Abfragevorgang zur Verfügung.
LINQ- und generische Typen (C#)
LINQ-Abfragen basieren auf generischen Typen. Sie benötigen kein fundiertes Wissen über Generika, bevor Sie mit dem Schreiben von Abfragen beginnen können. Möglicherweise möchten Sie jedoch zwei grundlegende Konzepte verstehen:
- Wenn Sie eine Instanz einer generischen Auflistungsklasse erstellen, wie List<T>, ersetzen Sie das „T“ durch den Typ der Objekte, die die Liste enthält. Beispielsweise wird eine Liste von Zeichenfolgen als ausgedrückt
List<string>
, und eine Liste vonCustomer
Objekten wird als ausgedrücktList<Customer>
. Eine generische Liste ist stark typisiert und bietet viele Vorteile gegenüber Sammlungen, die ihre Elemente als Object speichern. Wenn Sie versuchen, einCustomer
zu einemList<string>
hinzuzufügen, wird zur Kompilierungszeit ein Fehler angezeigt. Es ist sehr leicht, generische Auflistungen zu verwenden, da Sie keine Laufzeitumwandlung von Typen durchführen müssen. - IEnumerable<T> ist die Schnittstelle, mit der generische Auflistungsklassen mithilfe der
foreach
Anweisung aufgezählt werden können. Generische Auflistungsklassen unterstützen IEnumerable<T>, während nicht generische Auflistungsklassen, wie etwa ArrayList, IEnumerable unterstützen.
Weitere Informationen zu Generika finden Sie unter Generics.
IEnumerable<T>-Variablen in LINQ-Abfragen
LINQ-Abfragevariablen sind als IEnumerable<T> oder als ein abgeleiteter Typ wie IQueryable<T> typisiert. Wenn eine Abfragevariable angezeigt wird, die als IEnumerable<Customer>
eingegeben wird, bedeutet dies lediglich, dass die Abfrage, wenn sie ausgeführt wird, eine Sequenz von Null oder mehr Customer
Objekten erzeugt.
IEnumerable<Customer> customerQuery = from cust in customers
where cust.City == "London"
select cust;
foreach (Customer customer in customerQuery)
{
Console.WriteLine($"{customer.LastName}, {customer.FirstName}");
}
Verwalten generischer Typdeklarationen durch den Compiler
Wenn Sie es vorziehen, können Sie generische Syntax vermeiden, indem Sie das Schlüsselwort var verwenden. Das var
Schlüsselwort weist den Compiler an, den Typ einer Abfragevariable abzuleiten, indem er die in der from
Klausel angegebene Datenquelle betrachtet. Im folgenden Beispiel wird der gleiche kompilierte Code wie im vorherigen Beispiel erzeugt:
var customerQuery2 = from cust in customers
where cust.City == "London"
select cust;
foreach(var customer in customerQuery2)
{
Console.WriteLine($"{customer.LastName}, {customer.FirstName}");
}
Das var
Schlüsselwort ist nützlich, wenn der Typ der Variablen offensichtlich ist oder wenn es nicht so wichtig ist, geschachtelte generische Typen wie gruppenabfragen explizit anzugeben. Im Allgemeinen empfiehlt es sich, wenn Sie verwenden var
, zu erkennen, dass der Code für andere Benutzer schwieriger zu lesen ist. Weitere Informationen finden Sie unter Implizit typierten lokalen Variablen.