.NET LINQ von Grund auf

Als Softwareentwickler verbringen wir viel Zeit damit, Daten aus vielen verschiedenen Datenquellen zu extrahieren und anzuzeigen. Egal, ob es sich um einen XML-Webservice oder um eine relationale Datenbank mit vollem Funktionsumfang handelt, wir mussten verschiedene Methoden des Datenzugriffs erlernen. Wäre es nicht toll, wenn die Zugriffsmethode für alle Datenquellen gleich wäre? Nun, wir haben Glück, denn seit der Veröffentlichung von C # 3.0 und .NET 3.5 Framework hat LINQ das Spiel für immer verändert.

Tutorial-Details

  • Einführung in die LINQ-Syntax
  • Projektionen mit LINQ
  • Daten verfeinern
  • Standardoperatoren

Überblick über den aktuellen Datenzugriff

Auf der .NET-Plattform haben und verwenden wir ADO.NET
für den Zugriff auf verschiedene Datenquellen. Die Open Source Community hat ebenfalls zur Verfügung gestellt
die Entwickler mit einer Reihe von Alternativen.

Language Integrated Query ist die neue Ergänzung zu .NET
Familie und wie der Name schon sagt, ist es die Art des Abfragestil-Datenzugriffs
wird vollständig von der Sprache unterstützt, um den Zugriff auf Daten effektiv zu vereinheitlichen
und um unser Leben leichter zu machen. LINQ kann eine Reihe verschiedener Quellen ansprechen, nämlich Oracle,
MSSQL, XML und ein paar andere, aber im Moment werden wir uns auf das grundlegendste konzentrieren
alle, LINQ to Objects.

LINQ zu Objekten

Normalerweise, um die Daten in unseren Listen zu verarbeiten und zu verfeinern
und verschiedene andere Datenstrukturen haben wir entweder die 'foreach'-Schleife oder eine andere verwendet
Art der Schleifenmethode, um die Objekte zu durchlaufen und sie nacheinander zu verarbeiten
einer gemäß einer Bedingung. Das ist in Ordnung, aber ehrlich gesagt, erfordert es viel
Grundlegende Codierung, die wir alle wünschen, nicht schreiben zu müssen. Im Wesentlichen mussten wir das sagen
Compiler jedes einzelne Detail des Prozesses, um die Daten zu manipulieren.

Genau hier glänzt LINQ am besten. Was uns LINQ erlaubt
Um dies zu tun, teilen Sie dem Compiler einfach mit, was wir tun möchten, und lässt den Compiler arbeiten
den besten Weg, um das tatsächlich zu erreichen. Wenn Sie zuvor die SQL-Syntax verwendet haben, ähneln die massiven Ähnlichkeiten
zwischen LINQ und allen Dialekten von SQL ist das erste, was Sie bemerken werden.
Wie SQL unterstützt auch LINQ "select", "from", "where", "join", "group by"
und "order by" Keywords. Hier ist ein einfaches Beispiel für das Abfragen einer Liste von Objekten:

Listeninitialisierung:

 Liste ListOfCars = neue Liste() neues Auto Name = "Toyota", Besitzer = "Alex", Modell = 1992, Neues Auto Name = "Mitsubishi", Besitzer = "Jeff", Modell = 2005, Neues Auto Name = "Land Rover ", owner =" Danny ", Modell = 2001, neues Auto name =" BMW ", owner =" Danny ", Modell = 2006, neues Auto name =" Subaru ", owner =" Smith ", Modell = 2003;

Die Abfrage:

 IEnumerable QueryResult = aus dem Auto in ListOfCars Auto auswählen;

Der erste Teil des vorhergehenden Codes füllt einfach eine Liste aus
mit vier Instanzen der Klasse "Auto". Der nächste Teil des Codes verwendet jedoch die
Schlüsselwörter "von" und "auswählen", um eine Gruppe von Objekten auszuwählen. Der Hauptunterschied
zwischen SQL und LINQ ist, dass das Schlüsselwort "from" vor dem "select" steht
Schlüsselwort, weil wir zuerst das Objekt definieren müssen, an dem wir arbeiten möchten. Endlich
Die "select" -Klausel teilt dem Compiler mit, was wir in dieser Abfrage extrahieren möchten. Obenstehendes
Code extrahiert einfach alles, was in der Liste enthalten ist, und weist es dem "QueryResult" zu.
Variable.

Wenn wir Dinge von Objekten abfragen (LINQ to Objects), dann
Abfragen geben immer ein "IEnumrable" zurück"Liste von Objekten. Im Wesentlichen die
Der Typ "IEnumerable" ist die Art der Liste, die den Enumerator verfügbar macht
unterstützt eine einfache Iteration über eine nicht generische Sammlung und
ist der Typ jedes Eintrags in der Liste.
Machen Sie sich keine Sorgen, wenn Sie mit "Enumeratoren" und "Generics" nicht vertraut sind. Gerade
Denken Sie daran, dass das Ergebnis von LINQ-Abfragen immer eine Sammlung wie Daten ist
Struktur, die es erlaubt, mit einer Schleife wie gezeigt zu iterieren
unten:

 foreach (Auto in QueryResult) Console.WriteLine (car.name);

Wir haben gelernt, dass LINQ immer eine ähnliche Sammlungsstruktur zurückgibt
zu allen anderen Listen. Die LINQ-Abfrage wird jedoch erst ausgeführt, wenn das Ergebnis vorliegt
Zugriff auf einen anderen Code, z. B. die oben beschriebene "foreach" -Schleife. Dies ist zum
Erlauben Sie uns, die Abfrage kontinuierlich zu definieren, ohne den Overhead durch erneute Auswertung zu definieren
jeder neue Schritt in der Abfrage.

Projektionen

So weit, ist es gut; Aber meistens werden unsere Anfragen benötigt
komplexer sein; Versuchen wir also, Daten zu projizieren. In SQL bedeutet Projektion Auswählen
der Name der Spalte (n) der Tabelle (n), die im Ergebnis angezeigt werden soll
der Abfrage. Bei LINQ to Objects wird die Projektion durchgeführt
in einem anderen Abfrageergebnistyp als dem Objekttyp, den wir ausführen
Abfrage am.

Es gibt zwei Arten von Projektionen, die wir ausführen können. Wir können
Führen Sie entweder eine Projektion basierend auf einem vorhandenen Objekttyp durch oder gehen Sie vollständig aus
Andersherum mit anonymen Typen. Das folgende Beispiel ist vom ersten
nett:

 IEnumerable QueryResult = aus dem Auto in ListOfCars wählen Sie das neue CarOwner owner_name = car.owner;

Im vorhergehenden Code wird der Typ des Abfrageergebnisses als deklariert
, das ist anders als , der Typ, mit dem die 'ListOfCar'-Variable initialisiert wird. Wir haben
hat auch das "neue" Schlüsselwort verwendet und einige Aufgaben innerhalb des geschweiften geleistet
Klammern. Im obigen Code wird der Befehl "select" mit dem Schlüsselwort "new" angezeigt
Compiler, um für jeden Eintrag im Abfrageergebnis ein neues 'CarOwner'-Objekt zu instanziieren.
Durch das Zuweisen von Werten zu dem neuen Typ haben wir jede Instanz initialisiert
der 'CarOwner' Klasse.

Wenn Sie jedoch noch keinen Typ definiert haben
verwenden, können Sie weiterhin Projektionen mit anonymen Typen durchführen.

Projektionen mit anonymen Typen

Es wäre ein großer Aufwand, wenn Sie für jede Projektion das tun würden
gezwungen, einen neuen Typ zu erstellen. Daher wird ab C # 3.0 die anonyme Unterstützung unterstützt
Typen wurden der Sprache hinzugefügt. Ein anonymer Typ wird mit "var" deklariert.
Stichwort. Es teilt dem Compiler mit, dass der Typ der Variablen bis nicht bekannt ist
es wird zum ersten Mal vergeben.

 var QueryResult = aus dem Auto in ListOfCars wählen Sie new car_name = car.name, owner_name = car.owner; foreach (var-Eintrag in QueryResult) Console.WriteLine (entry.car_name);

Das Obige ist ein Beispiel für das Durchführen einer Abfrage mit Anonymous
Typen. Der einzige Haken ist, dass der Compiler dies nicht tun wird
zulassen, dass anonyme Typen aus Methoden zurückgegeben werden.

Der Zugriff auf die Eigenschaften eines anonymen Typs ist einfach. In Visual Studio 2008 der Code
Completion / Intellisense listet auch die Eigenschaften auf, die vom anonymen Typ verfügbar gemacht werden.

Daten verfeinern

Normalerweise müssen wir als Teil der LINQ-Abfrage auch die
Abfrageergebnis durch Angabe einer Bedingung. Genau wie SQL verwendet auch LINQ das "wo"
Klausel, um dem Compiler mitzuteilen, welche Bedingungen akzeptabel sind.

 IEnumerable QueryResult = aus dem Auto in ListOfCars wobei car.name == "Subaru" das Auto auswählt;

Der vorhergehende Code demonstriert die Verwendung der "wo" -Klausel und
die Bedingung zu folgen. Zur weiteren Definition mehrerer Bedingungen unterstützt LINQ
die Konstrukte 'und' (&& amp) und 'oder' (||). Der "wo" -Teil der Abfrage muss immer ein sein
Boolescher Ausdruck, sonst beschwert sich der Compiler.

Sortieren nach

Bei der Abfrage von Objekten können Sie sich auf die Abfrage verlassen
Ziel ist bereits sortiert. Ist dies nicht der Fall, kann LINQ sich darum kümmern
indem Sie die "order by" -Klausel verwenden, die sicherstellt, dass das Ergebnis Ihrer Abfrage ist
richtig sortiert.

 IEnumerable QueryResult = aus dem Auto in ListOfCars nach dem Auto-Modell Auto auswählen;

Wenn Sie den obigen Code ausführen, sehen Sie das Ergebnis von
Abfrage ist aufsteigend sortiert. Sie können die Reihenfolge ändern, indem Sie "aufsteigend" und "absteigend" verwenden.
Schlüsselwörter und ändern Sie außerdem die Reihenfolge, indem Sie mehr als ein zu sortierendes Feld angeben
durch. Der folgende Code zeigt wie:

 IEnumerable QueryResult = vom Auto in ListOfCars geordnet nach Auto.Modell absteigend Auto auswählen;

Gruppierung

LINQ ermöglicht auch das Gruppieren des Abfrageergebnisses nach dem Wert von a
spezifische Eigenschaft wie in diesem Beispiel gezeigt:

 var QueryResult = aus dem Auto in der ListOfCars-Gruppe Auto von car.owner in carOwnersGroup select carOwnersGroup.Key;

Wie Sie sehen, unterstützt LINQ die Klausel "Gruppieren nach"
Geben Sie an, nach welchem ​​Objekt und nach welcher Eigenschaft gruppiert werden soll. Das Schlüsselwort "into" wird
lassen Sie uns dann auf ein Gruppierungsergebnis projizieren, auf das mit dem "Schlüssel" zugegriffen werden kann
Eigentum.

Schließt sich an

LINQ unterstützt das Zusammenfügen von Daten aus verschiedenen Sammlungen in einer
Abfrageergebnis. Sie können dies mit dem Schlüsselwort "join" tun, um die Objekte anzugeben
beitreten und mit dem Schlüsselwort "on" die passende Beziehung zwischen angeben
die zwei Objekte.

Themenliste initialisieren:

 Liste ListOfCars = neue Liste() neues Auto Name = "Mitsubishi", Besitzer = "Jeff", Modell = 2005, Neues Auto Name = "Land Rover", Besitzer = "Danny", Modell = 2001, Neues Auto Name = " Subaru ", Besitzer =" Smith ", Modell = 2003, neues Auto Name =" Toyota ", Besitzer =" Alex ", Modell = 1992, neues Auto Name =" BMW ", Besitzer =" Danny ", Modell = 2006,; Liste ListOfCarOwners = neue Liste() new CarOwner owner_name = "Danny", Alter = 22, neuer CarOwner owner_name = "Jeff", Alter = 35, neuer CarOwner owner_name = "Smith", Alter = 19, neuer CarOwner owner_name = "Alex", Alter = 40;

Abfrage:

 var QueryResult = aus dem Auto in ListOfCars tritt dem Carowner in ListOfCarOwners bei car.owner gleich carowner.owner_name bei. select new name = car.name, owner = car.owner, owner_age = carowner.age;

Im obigen Code haben wir uns mit einem anonymen Typ verbunden
die zwei Objekte in einer einzigen Abfrage ergeben.

Objekthierarchien mit Gruppenverknüpfungen

Bisher haben wir gelernt, wie wir LINQ nutzen können, um eine Wohnung zu bauen
Abfrageergebnis der Liste. Mit LINQ ist auch eine hierarchische Abfrage möglich
Ergebnis mit "GroupJoin". In einfachen Worten könnten wir Objekte zuweisen
Eigenschaften jedes Eintrags mit LINQ-Abfrage.

 Liste ListOfCars = neue Liste() neues Auto Name = "Mitsubishi", Besitzer = "Jeff", Modell = 2005, Neues Auto Name = "Land Rover", Besitzer = "Danny", Modell = 2001, Neues Auto Name = " Subaru ", Besitzer =" Smith ", Modell = 2003, neues Auto Name =" Toyota ", Besitzer =" Alex ", Modell = 1992, neues Auto Name =" BMW ", Besitzer =" Danny ", Modell = 2006,; Liste ListOfCarOwners = neue Liste() new CarOwner owner_name = "Danny", Alter = 22, neuer CarOwner owner_name = "Jeff", Alter = 35, neuer CarOwner owner_name = "Smith", Alter = 19, neuer CarOwner owner_name = "Alex", Alter = 40; var QueryResult = vom Carowner in ListOfCarOwners tritt in ListOfCars auf carowner.owner_name das Auto gleich car.owner in carsGroup ein. select new name = carowner.owner_name, cars = carsGroup; foreach (var carOwner in QueryResult) foreach (var auto in carOwner.cars) Console.WriteLine ("Eigentümername: 0, Name des Autos: 1, Fahrzeugmodell: 2"), carOwner.name, car.name , Auto Model);

Im obigen Beispiel folgt auf die "Join" -Klausel ein "into"
Teil. Dies unterscheidet sich vom vorherigen Join-Vorgang, den wir uns angesehen haben. Hier das "in"
Klausel wird verwendet, um Autos vom Eigentümer zu gruppieren (in carsGroup) und die Gruppierung der Gruppe zuzuordnen
"Autos" Eigenschaft des anonymen Typs.

Standardabfrageoperatoren

Bisher wurde alles, was wir gesehen haben, von C # 3.0 unterstützt
Syntax. Es gibt jedoch immer noch eine große Anzahl von Vorgängen, die C # 3.0 nicht ausführt
Unterstützung. Die Standardabfrageoperatoren bieten Abfragefunktionen einschließlich
Filterung, Projektion, Aggregation, Sortierung und mehr. Diese Operationen werden daher unterstützt
als Methoden der LINQ-Bibliothek und kann auf Ergebnis einer Abfrage ausgeführt werden, wie in gezeigt
Folgender Screenshot:

Diese Operatoren sind nachstehend als Referenz aufgeführt.

Aggregierte Operatoren

  • Summe: gibt die Summe aller Einträge zurück
  • Max: gibt den Eintrag mit dem Maximalwert zurück
  • Mindest: gibt den Eintrag mit dem Mindestwert zurück
  • Durchschnittlich: gibt den Durchschnittswert für die Sammlung zurück
  • Aggregat: wird zum Erstellen einer benutzerdefinierten Aggregation verwendet
  • LongCountHinweis: Wenn Sie mit einer großen Sammlung arbeiten, gibt diese Methode einen Wert zurück, der den höchsten Wert der Klasse "long" unterstützt
  • Anzahl: Gibt eine "Ganzzahl" für die Anzahl der Elemente in der Auflistung zurück

Elementoperatoren

  • Zuerst: gibt den ersten Eintrag aus der Ergebnissammlung zurück
  • FirstOrDefault: Wenn die leere Sammlung leer ist, wird der Standardwert zurückgegeben. Andernfalls wird der erste Eintrag aus der Sammlung zurückgegeben
  • Single: gibt nur ein Element aus der Sammlung zurück
  • SingleOrDefault: Wenn die leere Sammlung leer ist, wird der Standardwert zurückgegeben. Andernfalls wird nur ein Element aus der Sammlung zurückgegeben
  • Zuletzt: gibt den letzten Eintrag aus der Sammlung zurück
  • LastOrDefault: Wenn die leere Sammlung leer ist, wird der Standardwert zurückgegeben. Andernfalls wird der letzte Eintrag aus der Sammlung zurückgegeben
  • ElementAt: gibt das Element an der angegebenen Position zurück
  • ElementAtOrDefault: Wenn die leere Sammlung leer ist, wird der Standardwert zurückgegeben. Andernfalls wird das Element an der angegebenen Position zurückgegeben

Stellen Sie verwandte Operatoren ein

  • Außer: Ähnlich wie beim linken Join in SQL, werden Einträge aus der einen Gruppe zurückgegeben, die in einer anderen Gruppe nicht vorhanden ist
  • Union: gibt alle Einträge von beiden Objekten zurück
  • Sich schneiden: Gibt die gleichen Elemente aus beiden Sätzen zurück
  • Eindeutig: gibt eindeutige Einträge aus der Sammlung zurück

Generierungsoperatoren

  • DefaultIfEmpty: Wenn das Ergebnis leer ist, wird der Standardwert zurückgegeben
  • Wiederholen: wiederholt sich bei der Rückgabe von Objekten für die angegebene Anzahl von Malen
  • Leeren: gibt eine leere IEnumerable-Auflistung zurück
  • Angebot: Gibt einen Zahlenbereich für eine angegebene Startnummer und Anzahl zurück

Verfeinerungsoperatoren

  • Woher: gibt Objekte zurück, die die angegebene Bedingung erfüllen
  • OfType: gibt Objekte des angegebenen Typs zurück

Konvertierungsoperatoren

  • Nachschlagen: gibt das Ergebnis als Lookup zurück
  • Auflisten: gibt das Ergebnis als Listensammlung zurück
  • ToDictionary: gibt das Ergebnis als Wörterbuch zurück
  • ToArray: gibt das Ergebnis als Array-Sammlung zurück
  • AsQueryable: gibt das Ergebnis als IQueryable zurück
  • AsUnumerable: gibt das Ergebnis als IEnumerable zurück
  • OfType: filtert die Sammlung nach dem angegebenen Typ
  • Besetzung: Wird verwendet, um eine schwach typisierte Sammlung in eine stark typisierte Sammlung zu konvertieren

Partitionierungsoperatoren

  • Nehmen: gibt eine angegebene Anzahl von Datensätzen zurück
  • Nehmen Sie doch: Gibt eine angegebene Anzahl von Datensätzen zurück, während die angegebene Bedingung als wahr ausgewertet wird
  • Überspringen: überspringt die angegebene Anzahl von Einträgen und gibt den Rest zurück
  • Überspringen: überspringt die angegebene Anzahl von Einträgen, während die angegebene Bedingung als wahr bewertet wird

Quantifizierer-Operatoren

  • Irgendein: gibt wahr oder falsch für eine angegebene Bedingung zurück
  • Enthält: Gibt wahr oder falsch zurück, wenn das angegebene Objekt vorhanden ist
  • Alles: Gibt true oder false für alle Objekte zurück, die die angegebene Bedingung erfüllen

Operator beitreten

  • Beitreten: gibt Einträge zurück, bei denen Schlüssel in Sätzen gleich sind
  • GroupJoin: Wird verwendet, um hierarchische Objekte basierend auf einer Master- und Detailbeziehung zu erstellen

Gleichheitsoperatoren

  • SequenceEqual: gibt true zurück, wenn die Kollektionen gleich sind

Sortieroperatoren

  • Umkehren: gibt eine umgekehrte Sammlung zurück
  • ThenBy: dient zur weiteren Sortierung
  • ThenByDescending: dient zur weiteren Sortierung in absteigender Reihenfolge
  • Sortieren nach: wird verwendet, um die Reihenfolge zu definieren
  • OrderByDescending: um absteigende Reihenfolge zu definieren

Projektionsoperatoren

  • SelectMany: Zum Abflachen einer hierarchischen Sammlung
  • Wählen: wird verwendet, um die Eigenschaften zu identifizieren, die zurückgegeben werden

Verkettungsoperatoren

  • Concat: wird verwendet, um zwei Sammlungen zu verketten

So was jetzt?

LINQ hat sich als sehr nützlich für die Abfrage von Objekten erwiesen, und die SQL-ähnliche Syntax macht es leicht
lernen und nutzen. Die große Anzahl von Standardoperatoren ermöglicht auch die Verkettung einer Reihe von Operatoren
komplexe Abfragen durchführen. In einem Follow-up zu diesem Lernprogramm wird beschrieben, wie LINQ verwendet werden kann
Abfragen von Datenbanken und XML-Inhalten…

Verkaufen Sie .NET-Skripts und -Komponenten auf CodeCanyon



  • Folgen Sie uns auf Twitter oder abonnieren Sie den Nettuts + RSS-Feed für die besten Webentwicklungs-Tutorials im Web.