Freigeben über


Schreiben Ihrer ersten LINQ-Abfrage (Visual Basic)

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:

  1. Rufen Sie die Datenquelle oder Quellen ab.

  2. Erstellen Sie die Abfrage.

  3. 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, , Whereund 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 evensQuerygespeichert. 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 evensQuerydie 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, Averageund 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.

Siehe auch