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.
Eine Abfrage ist ein Ausdruck, der Daten aus einer Datenquelle abruft. Abfragen werden in einer dedizierten Abfragesprache ausgedrückt. Im Laufe der Zeit wurden verschiedene Sprachen für verschiedene Arten von Datenquellen entwickelt, z. B. SQL für relationale Datenbanken und XQuery für XML. Dadurch muss der Anwendungsentwickler eine neue Abfragesprache für jeden unterstützten Datenquellen- oder Datenformattyp erlernen.
Language-Integrated Query (LINQ) vereinfacht die Situation, indem ein konsistentes Modell zum Arbeiten mit Daten in verschiedenen Arten von Datenquellen und Formaten angeboten wird. In einer LINQ-Abfrage arbeiten Sie immer mit Objekten. Sie verwenden dieselben grundlegenden Codierungsmuster zum Abfragen und Transformieren von Daten in XML-Dokumenten, SQL-Datenbanken, ADO.NET Datasets und Entitäten, .NET Framework-Auflistungen und allen anderen Quellen oder Formaten, für die ein LINQ-Anbieter verfügbar ist. In diesem Dokument werden die drei Phasen der Erstellung und Verwendung grundlegender LINQ-Abfragen beschrieben.
Drei Phasen eines Abfragevorgangs
LINQ-Abfragevorgänge bestehen aus drei Aktionen:
Rufen Sie die Datenquelle oder Quellen ab.
Erstellen Sie die Abfrage.
Führen Sie die Abfrage aus.
In LINQ unterscheidet sich die Ausführung einer Abfrage von der Erstellung der Abfrage. Sie rufen keine Daten nur durch Erstellen einer Abfrage ab. Dieser Punkt wird weiter unten in diesem Thema ausführlicher behandelt.
Das folgende Beispiel veranschaulicht die drei Teile eines Abfragevorgangs. Im Beispiel wird ein Array ganzzahliger Zahlen als praktische Datenquelle für Demonstrationszwecke verwendet. Die gleichen Konzepte gelten jedoch auch für andere Datenquellen.
Hinweis
Stellen Sie auf der Kompilierungsseite von Project Designer (Visual Basic) sicher, dass "Option infer " auf "Ein" festgelegt ist.
' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}
' Query creation.
Dim evensQuery = From num In numbers
Where num Mod 2 = 0
Select num
' Query execution.
For Each number In evensQuery
Console.Write(number & " ")
Next
Ausgabe:
0 2 4 6
Die Datenquelle
Da es sich bei der Datenquelle im vorherigen Beispiel um ein Array handelt, unterstützt sie implizit die generische IEnumerable<T> Schnittstelle. Es ist diese Tatsache, dass Sie ein Array als Datenquelle für eine LINQ-Abfrage verwenden können. Typen, die IEnumerable<T> oder eine abgeleitete Schnittstelle unterstützen, z. B. die generischen IQueryable<T>, werden als abfragbare Typen bezeichnet.
Als implizit abfragbarer Typ erfordert das Array keine Änderung oder spezielle Behandlung, um als LINQ-Datenquelle zu dienen. Dasselbe gilt für alle Auflistungstypen, die List<T>Dictionary<TKey,TValue>die Generischen Klassen und andere Klassen in der .NET Framework-Klassenbibliothek unterstützenIEnumerable<T>.
Wenn die Quelldaten noch nicht implementiert IEnumerable<T>werden, ist ein LINQ-Anbieter erforderlich, um die Funktionalität der Standardabfrageoperatoren für diese Datenquelle zu implementieren. Beispielsweise behandelt LINQ to XML die Arbeit des Ladens eines XML-Dokuments in einen abfragefähigen XElement Typ, wie im folgenden Beispiel gezeigt. Weitere Informationen zu Standardabfrageoperatoren finden Sie unter "Übersicht über Standardabfrageoperatoren" (Visual Basic).
' Create a data source from an XML document.
Dim contacts = XElement.Load("c:\myContactList.xml")
Mit LINQ to SQL erstellen Sie zunächst zur Entwurfszeit eine objektrelationale Zuordnung, entweder manuell oder mithilfe der LINQ to SQL Tools in Visual Studio in Visual Studio . Sie schreiben Ihre Abfragen für die Objekte, und zur Laufzeit verarbeitet LINQ to SQL die Kommunikation mit der Datenbank. Im folgenden Beispiel customers
stellt eine bestimmte Tabelle in der Datenbank dar und Table<TEntity> unterstützt generische IQueryable<T>.
' Create a data source from a SQL table.
Dim db As New DataContext("C:\Northwind\Northwnd.mdf")
Dim customers As Table(Of Customer) = db.GetTable(Of Customer)
Weitere Informationen zum Erstellen bestimmter Arten von Datenquellen finden Sie in der Dokumentation für die verschiedenen LINQ-Anbieter. (Eine Liste dieser Anbieter finden Sie unter LINQ (Language-Integrated Query).) Die Grundregel ist einfach: Eine LINQ-Datenquelle ist jedes Objekt, das die generische IEnumerable<T> Schnittstelle unterstützt, oder eine Schnittstelle, die von ihr erbt.
Hinweis
Typen, z ArrayList . B. die nicht generische IEnumerable Schnittstelle unterstützen, können auch als LINQ-Datenquellen verwendet werden. Ein Beispiel, das ein ArrayList, siehe How to: Query an ArrayList with LINQ (Visual Basic).
Die Abfrage
In der Abfrage geben Sie an, welche Informationen Aus der Datenquelle oder Quellen abgerufen werden sollen. Sie haben auch die Möglichkeit, anzugeben, wie diese Informationen sortiert, gruppiert oder strukturiert werden sollen, bevor sie zurückgegeben wird. Zum Aktivieren der Abfrageerstellung hat Visual Basic neue Abfragesyntax in die Sprache integriert.
Wenn sie ausgeführt wird, gibt die Abfrage im folgenden Beispiel alle geraden Zahlen aus einem ganzzahligen Array zurück. numbers
' Data source.
Dim numbers() As Integer = {0, 1, 2, 3, 4, 5, 6}
' Query creation.
Dim evensQuery = From num In numbers
Where num Mod 2 = 0
Select num
' Query execution.
For Each number In evensQuery
Console.Write(number & " ")
Next
Der Abfrageausdruck enthält drei Klauseln: From
, , Where
und Select
. Die spezifische Funktion und der Zweck jeder Abfrageausdrucksklausel werden in basic Query Operations (Visual Basic) erläutert. Weitere Informationen finden Sie unter "Abfragen". Beachten Sie, dass in LINQ häufig eine Abfragedefinition in einer Variablen gespeichert und später ausgeführt wird. Die Abfragevariable, z evensQuery
. B. im vorherigen Beispiel, muss ein abfragebarer Typ sein. Der Typ von evensQuery
wird IEnumerable(Of Integer)
vom Compiler mithilfe der lokalen Typ-Ableitung zugewiesen.
Es ist wichtig zu beachten, dass die Abfragevariable selbst keine Aktion ausführt und keine Daten zurückgibt. Sie speichert nur die Abfragedefinition. Im vorherigen Beispiel ist es die For Each
Schleife, die die Abfrage ausführt.
Abfrageausführung
Die Abfrageausführung ist von der Abfrageerstellung getrennt. Die Abfrageerstellung definiert die Abfrage, die Ausführung wird jedoch durch einen anderen Mechanismus ausgelöst. Eine Abfrage kann ausgeführt werden, sobald sie definiert ist (sofortige Ausführung), oder die Definition kann gespeichert werden, und die Abfrage kann später ausgeführt werden (verzögerte Ausführung).
Verzögerte Ausführung
Eine typische LINQ-Abfrage ähnelt dem im vorherigen Beispiel, in dem evensQuery
definiert ist. Sie erstellt die Abfrage, führt sie aber nicht sofort aus. Stattdessen wird die Abfragedefinition in der Abfragevariablen evensQuery
gespeichert. Sie führen die Abfrage später aus, in der Regel mithilfe einer For Each
Schleife, die eine Abfolge von Werten zurückgibt, oder indem Sie einen Standardabfrageoperator anwenden, z Count
. B. oder Max
. Dieser Prozess wird als verzögerte Ausführung bezeichnet.
' Query execution that results in a sequence of values.
For Each number In evensQuery
Console.Write(number & " ")
Next
' Query execution that results in a single value.
Dim evens = evensQuery.Count()
Bei einer Abfolge von Werten greifen Sie mithilfe der Iterationsvariablen in der For Each
Schleife (number
im vorherigen Beispiel) auf die abgerufenen Daten zu. Da die Abfragevariable evensQuery
die Abfragedefinition anstelle der Abfrageergebnisse enthält, können Sie eine Abfrage beliebig oft ausführen, indem Sie die Abfragevariable mehrmals verwenden. Sie können beispielsweise über eine Datenbank in Ihrer Anwendung verfügen, die ständig von einer separaten Anwendung aktualisiert wird. Nachdem Sie eine Abfrage erstellt haben, die Daten aus dieser Datenbank abruft, können Sie eine Schleife verwenden For Each
, um die Abfrage wiederholt auszuführen, wobei die aktuellsten Daten jedes Mal abgerufen werden.
Das folgende Beispiel veranschaulicht, wie die verzögerte Ausführung funktioniert. Nachdem sie evensQuery2
mit einer For Each
Schleife definiert und ausgeführt wurde, wie in den vorherigen Beispielen, werden einige Elemente in der Datenquelle numbers
geändert. Anschließend wird eine zweite For Each
Schleife erneut ausgeführt evensQuery2
. Die Ergebnisse unterscheiden sich das zweite Mal, da die For Each
Schleife die Abfrage erneut ausführt, wobei die neuen Werte in numbers
.
Dim numberArray() = {0, 1, 2, 3, 4, 5, 6}
Dim evensQuery2 = From num In numberArray
Where num Mod 2 = 0
Select num
Console.WriteLine("Evens in original array:")
For Each number In evensQuery2
Console.Write(" " & number)
Next
Console.WriteLine()
' Change a few array elements.
numberArray(1) = 10
numberArray(4) = 22
numberArray(6) = 8
' Run the same query again.
Console.WriteLine(vbCrLf & "Evens in changed array:")
For Each number In evensQuery2
Console.Write(" " & number)
Next
Console.WriteLine()
Ausgabe:
Evens in original array:
0 2 4 6
Evens in changed array:
0 10 2 22 8
Sofortige Ausführung
Bei verzögerter Ausführung von Abfragen wird die Abfragedefinition für die spätere Ausführung in einer Abfragevariable gespeichert. Bei der sofortigen Ausführung wird die Abfrage zum Zeitpunkt der Definition ausgeführt. Die Ausführung wird ausgelöst, wenn Sie eine Methode anwenden, die Zugriff auf einzelne Elemente des Abfrageergebnisses erfordert. Die sofortige Ausführung wird häufig mithilfe eines der Standardabfrageoperatoren erzwungen, die einzelne Werte zurückgeben. Beispiele sind Count
: , Max
, Average
und First
. Diese Standardabfrageoperatoren führen die Abfrage aus, sobald sie angewendet werden, um ein Singleton-Ergebnis zu berechnen und zurückzugeben. Weitere Informationen zu Standardabfrageoperatoren, die einzelne Werte zurückgeben, finden Sie unter Aggregationsvorgänge, Elementoperationen und Quantifiziereroperationen.
Die folgende Abfrage gibt die Anzahl der geraden Zahlen in einem Array ganzzahliger Zahlen zurück. Die Abfragedefinition wird nicht gespeichert und numEvens
ist einfach Integer
.
Dim numEvens = (From num In numbers
Where num Mod 2 = 0
Select num).Count()
Sie können dasselbe Ergebnis mithilfe der Aggregate
Methode erzielen.
Dim numEvensAgg = Aggregate num In numbers
Where num Mod 2 = 0
Select num
Into Count()
Sie können die Ausführung einer Abfrage auch erzwingen, indem Sie die ToList
Abfrage ToArray
oder Methode für eine Abfrage (direkt) oder Abfragevariable (verzögert) aufrufen, wie im folgenden Code gezeigt.
' Immediate execution.
Dim evensList = (From num In numbers
Where num Mod 2 = 0
Select num).ToList()
' Deferred execution.
Dim evensQuery3 = From num In numbers
Where num Mod 2 = 0
Select num
' . . .
Dim evensArray = evensQuery3.ToArray()
In den vorherigen Beispielen evensQuery3
handelt es sich um eine Abfragevariable, ist aber evensList
eine Liste und evensArray
ein Array.
Das Verwenden ToList
oder ToArray
Erzwingen der sofortigen Ausführung ist besonders in Szenarien hilfreich, in denen Sie die Abfrage sofort ausführen und die Ergebnisse in einem einzelnen Auflistungsobjekt zwischenspeichern möchten. Weitere Informationen zu diesen Methoden finden Sie unter Konvertieren von Datentypen.
Sie können auch dazu führen, dass eine Abfrage mithilfe einer IEnumerable
Methode wie der IEnumerable.GetEnumerator Methode ausgeführt wird.