LINQ – Verstehen und Einsetzen - Software and Systems Engineering

Werbung
Technische Universität München
LINQ – Verstehen und Einsetzen
Proseminar Objektorientiertes Programmieren mit .NET und C#
Georg Wagner
Institut für Informatik
Software & Systems Engineering
Technische Universität München
Agenda
1
2
3
4
5
17.12.10
LINQ-Einführung (Motivation, Bestandteile)
C#-Spracherweiterungen (kleine Kontrollfrage)
LINQ-Abfragearten
LINQ unter der Lupe (Verzögerte Ausführung)
LINQ to SQL
LINQ – Verstehen und Einsetzen
v. Georg Wagner
2
Technische Universität München
1. Einführung zu LINQ
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
3
Technische Universität München
LINQ – Die universelle Abfragesprache
Language INtegrated Queries
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
4
Technische Universität München
Motivationstreiber zur Einführung von LINQ
Es wird aus verschiedenen Datenquellen ermittelt, wer heute Geburtstag hat:
Datenquellen:
<Student>
<Name>
<Birthday>
<MatrNr>
</Student> …
MS-SQL DB
DataSet
Programmiersprache:
LINQ
WIEDER
ANDERER CODE
Ein einheitlicher
Zugriffscode
Ergebnis:
Heute haben Geburtstag: Herbert, Anton, Fritz…
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
5
Technische Universität München
LINQ-Bestandteile
Programmiersprachen
C#
VB.NET
F#
LINQ-Bausteine
Abfrageausdrücke
Standard Abfrageoperatoren
Expression Trees
LINQ-Provider
LINQ2Objects
Datenquellen
LINQ2XML
<Student>
<Vorname>
<Nachname>
<MatrNr>
</Student> …
LINQ2SQL
LINQ2Datase
t
MS-SQL DB
DataSet
17.12.10
LINQ2Entities
LINQ – Verstehen und Einsetzen
v. Georg Wagner
ADO.NET Entity
Framework
6
Technische Universität München
Agenda
1
2
3
4
5
17.12.10
LINQ-Einführung (Motivation, Bestandteile)
C#-Spracherweiterungen (kleine Kontrollfrage)
LINQ-Abfragearten
LINQ unter der Lupe (Verzögerte Ausführung)
LINQ to SQL
LINQ – Verstehen und Einsetzen
v. Georg Wagner
7
Technische Universität München
2. C#-Spracherweiterungen
Spracherweiterungen zum Verstehen von LINQ
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
8
Technische Universität München
Implizit typisierte lokale Variable
Der Compiler leitet für die var-Deklaration implizit den Variablentyp
aus der Initialisierung der Variable ab. "
„var“ darf nur lokal verwendet werden.
Objekt-Initialisierer
Objekt-Initialisierer
Objekt-Initialisierer nehmen Schreibarbeit ab und initialisieren
öffentliche Felder bzw. öffentliche Eigenschaften nach ihrer
Instanziierung.
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
9
Technische Universität München
Anonyme Typen
Zweck:Schnelles Gruppieren von Daten in ein Objekt, ohne dass
man explizit eine Klasse deklarieren muss:
1.  Intern entsteht ein Typ mit den Eigenschaften Platz, Vorname und
Nachname, der sog. Anonyme Typ.
2.  Dieser Typ wird mit rangliste.Platz, rangliste.Vorname usw.
initialisiert. 3.  Am Schluss erhält sprinter die Referenz zum Anonymen Typen.
Äquivalent ist auch:
17.12.10
(Namen der Eigenschaften werden übernommen)
LINQ – Verstehen und Einsetzen
v. Georg Wagner
10
Technische Universität München
Erweiterungsmethoden
Mit Erweiterungsmethoden kann man bereits definierte Typen nachträglich
Methoden hinzufügen. Kennzeichnet
welcher Typ zu
erweitern ist.
…
Wenn man nun mit Instanzen arbeitet die IEnumerable<TSource> implementieren (wie
z.B. List<Student>) kann man die Erweiterungsmethode abrufen. IntelliSense zeigt
sie mit einem blauen Pfeil an:
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
11
Technische Universität München
Lambda-Ausdrücke
Mit Lambda-Ausdrücken wird das Einfügen von Code an Stellen erlaubt,
wo man eigentlich eine Methoden-Übergabe an ein Delegate erwartet hätte.
…
…
Eingabe-Parameter (Typ wird selbst
abgeleitet) – Muss mit den
Parametern des Delegates Func
(hier: TSource) entsprechen.
17.12.10
Lambda-Operator Ausdruck oder Anweisungsblock
Rückgabetyp muss mit dem des
Delegates (hier: Boolean)
übereinstimmen.
LINQ – Verstehen und Einsetzen
v. Georg Wagner
12
Technische Universität München
Kontroll-Frage
2 Parameter deklariert
…
nur 1 Parameter
übergeben
Warum funktioniert der Where-Aufruf obwohl nur der 2.
Parameter übergeben wurde?
Wenn man auf das, was man zugreift (den Typ bei this), noch als Parameter
angeben würde, hätte man immer eine unnötige redundante Information.
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
13
Technische Universität München
Agenda
1
2
3
4
5
17.12.10
LINQ-Einführung (Motivation, Bestandteile)
C#-Spracherweiterungen (kleine Kontrollfrage)
LINQ-Abfragearten
LINQ unter der Lupe (Verzögerte Ausführung)
LINQ to SQL
LINQ – Verstehen und Einsetzen
v. Georg Wagner
14
Technische Universität München
3. LINQ-Abfragearten
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
15
Technische Universität München
LINQ-Abfrageausdrücke
Das Datenobjekt studenten wird durch einen LINQ-Abfrageausdruck ausgefiltert: "
„Suche alle Studenten, die unser Proseminar machen und sortiere sie dem
Vornamen nach absteigend geordnet.“
vom Typ
IEnumerable<Student>
§ 
Jede Abfrage beginnt mit from und endet mit select (oder group).
„studenten“ repräsentiert ein Objekt, das vom Typ IEnumerable<Student>
ist
§ 
Jedes Objekt, das IEnumerable<T> implementiert, wird im LINQ-Vokabular
„Sequenz“ genannt. § 
studenten kann somit jedes beliebige Objekt sein, dass IEnumerable<T>
implementiert (z.B. Array, List, Dictionary, …)
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
16
Technische Universität München
LINQ-Abfrageausdrücke
implizit typisierte lokale
Variable
Iterator
vom Typ
IEnumerable<Student>
Um alle gefundene Studenten auszugeben nutzen wir:
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
17
Technische Universität München
LINQ-Abfrageoperatoren
Lambda-Ausdruck
Erweiterungsmethoden
Allgemein gilt:
IEnumerable<T>-Erweiterungsmethoden geben IEnumerable<T>
Typen zurück -> Möglichkeit der Verkettung -> Pipeline Pattern
In unserem speziellen Fall ist der Typ jeweils: List<Student> 17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
18
Technische Universität München
Abfrageausdrücke vs. Abfrageoperatoren
Man muss sich gar nicht für eine Art entscheiden, beide sind kombinierbar!
- Abfrageausdrücke sind durch Ihre Kompaktheit meistens lesbarer
- Aber: Unterstützen nur die Operatoren:
17.12.10
Select
GroupBy
SelectMany
Let
Join
Cast
GroupJoin
OrderBy/ThenBy
LINQ – Verstehen und Einsetzen
v. Georg Wagner
19
Technische Universität München
Agenda
1
2
3
4
5
17.12.10
LINQ-Einführung (Motivation, Bestandteile)
C#-Spracherweiterungen (kleine Kontrollfrage)
LINQ-Abfragearten
LINQ unter der Lupe (Verzögerte Ausführung)
LINQ to SQL
LINQ – Verstehen und Einsetzen
v. Georg Wagner
20
Technische Universität München
4. LINQ-Abfragen unter der
Lupe
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
21
Technische Universität München
LINQ-Abfragen unter der Lupe
Schauen wir uns ein einfacheres Beispiel genauer an:
Um die Ergebnisse auszugeben haben wir verwendet:
Da „teilnehmer“ mit „person“ durchiteriert wird, enthält „teilnehmer“ bereits alle
ausgefilterten Ergebnisse.
FALSCH: „teilnehmer“ enthält im Vorhinein noch keine Ergebnisse. 17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
22
Technische Universität München
LINQ-Abfragen unter der Lupe
Bei der Kompilierung wird die Abfrage so repräsentiert:
= Verzögerte "
Ausführung
Jedes mal, wenn der Iterator person von teilnehmer ein Element verlangt, wird der
obige Code ausgeführt.
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
23
Technische Universität München
Verzögerte Ausführung von Abfragen
Verzögerte Ausführung erreicht man durch sog. Co-Routinen. Where
und Select gehören zu solchen.
Where-Methode (Co-Routine):
1. 
2. 
3. 
4. 
Aufrufer der Co-Routine:
Co-Routinen werden mit yield return gekennzeichnet.
yield return gibt nicht IEnumerable<TSource> sondern ein Element von TSource zurück
Nach jedem yield return wird die Kontrolle dem Aufrufer zurückgegeben
Bei weiteren Aufrufe mit demselben Iterator person wird die Co-Routine am letzten yield
return fortgesetzt. Dies geschieht hier so lange, bis in source kein element mehr existiert.
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
24
Technische Universität München
Verzögerte Ausführung von Abfragen
Select() iteriert in einer foreach-Schleife Ergebnisse von Where(). Gibt Where() mit yield return
ein Element zurück, gibt Select() dieses Element ebenso mit yield return ein Element
zurück Durch Verzögerte Ausführung bei großen Datensatzmengen muss bei der ersten Iteration
nicht lange gewartet werden und erfolgt keine große Zwischenspeicherung
Dieser Effekt geht durch Sortier, Gruppier oder Aggregier-Erweiterungsmethoden verloren
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
25
Technische Universität München
Agenda
1
2
3
4
5
17.12.10
LINQ-Einführung (Motivation, Bestandteile)
C#-Spracherweiterungen (kleine Kontrollfrage)
LINQ-Abfragearten
LINQ unter der Lupe (Verzögerte Ausführung)
LINQ to SQL
LINQ – Verstehen und Einsetzen
v. Georg Wagner
26
Technische Universität München
5. LINQ To SQL
Mappen, Abfragen, Verändern
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
27
Technische Universität München
Beispiel vom vorigen Vortrag in LINQ
SELECT DISTINCT c.[CustomerID] ,c.[CompanyName]
FROM [Northwind].[dbo].[Customers] c
JOIN [Northwind].[dbo].[Orders] o on c.CustomerID = o.CustomerID
JOIN [Northwind].[dbo].[Employees] e on o.EmployeeID = e.EmployeeID
WHERE e.EmployeeID = ‘1‘
ODER BY c.[CustomerID]
„Ermittle alle verschiedene Firmenkunden mit Ihren Kunden-IDs, die Aufträge bei
uns haben die unser Mitarbeiter mit der Firmen-ID 9 bearbeitet, und ordne sie nach
deren Kunden-IDs.“
Zur Realisation dieser Anfrage in LINQ brauchen wir: Eine Klasse, die LINQAbfragen in äquivalente SQL-Abfragen des Ziel-Dialektes übersetzt.
Lösung: Verwendung der DataContext Klasse aus System.Data.Linq
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
28
Technische Universität München
ADO.NET Beispiel vom vorigen Vortrag in LINQ
Bevor wir mittels DataContext Daten aus SQL-Tabellen lesen können,
müssen wir das relationale Modell auf das Objektmodell mappen. D.h. wir
müssen in unserem Fall folgende Zuordnungen machen:
Tabelle
Klasse
Eigenschaft
Attribut
Mapping-Möglichkeiten:
Attribute innerhalb "
Klassen
17.12.10
LINQ – Verstehen und Einsetzen
XMLDateien
v. Georg Wagner
LINQ to SQL
Designer
29
Technische Universität München
Objektrelationales Mapping via Klassen-Attributen
Zum Mappen werden die Klassen in System.Data.Linq.Mapping verwendet
Klasse Customer wird der SQL-Tabelle
Customer zugeordnet – Namen
müssen übereinstimmen!
Klassen-Eigenschaften werden zu den
Attributen der SQL-Tabelle Customer
zugeordnet – Namen müssen
übereinstimmen!
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
30
Technische Universität München
Der Code um der eigentlichen LINQ Abfrage
Eine Verbindung zu einem
SQL-Server wird hergestellt
Tabellen werden noch "
nicht eingelesen (Verzögert
Ausführung)
…
Ab der ersten Iteration wird eine
Anfrage in SQL-Syntax zum SQLServer geschickt
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
31
Technische Universität München
Die LINQ-Abfrage
Anfrage, die wir in LINQ realisieren sollten:
SELECT DISTINCT c.[CustomerID] ,c.[CompanyName]
FROM [Northwind].[dbo].[Customers] c
JOIN [Northwind].[dbo].[Orders] o on c.CustomerID = o.CustomerID
JOIN [Northwind].[dbo].[Employees] e on o.EmployeeID = e.EmployeeID
WHERE e.EmployeeID = ‚1'
ODER BY c.[CustomerID]
Die LINQ-Anfrage:
Objekt-Initialisierer
da nur ein Objekt zurückgegeben
werden kann, wird ein anonymer Typ
definiert. 17.12.10
Da das Distinct-Schlüsselwort in
Abfrageausdrücken nicht vorhanden ist, wird auf
LINQ-Abfrageoperatoren zurückgegriffen
LINQ – Verstehen und Einsetzen
v. Georg Wagner
32
Technische Universität München
Die LINQ-Abfrage
Die LINQ-Anfrage:
Zum SQL-Server wird gesendet (ab ersten foreach-Iteration):
SELECT DISTINCT [t0].[CustomerID], [t0].[CompanyName]
FROM [dbo].[Customers] AS [t0]
INNER JOIN [dbo].[Orders] AS [t1] ON [t0].[CustomerID] = [t1].[CustomerID]
INNER JOIN [dbo].[Employees] AS [t2] ON [t1].[EmployeeID] = [t2].[EmployeeID]
WHERE [t2].[EmployeeID] = 1
Bemerkenswert ist, dass LINQ durch die Angabe des anonymen Typen und des
anschließenden Distinct-Operators die Anfrage entsprechend minimiert hat.
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
33
Technische Universität München
Aktualisieren von Daten
Die Auftrags-Nummern 1 bis 10 wurden in Auftrags-Nr. 123 zusammengeführt. Eine
Aktualisierung der Daten ist also nötig.
Da die nötige Tabellen schon gemappt sind gestaltet sich eine Daten-Aktualisierung
sehr einfach:
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
34
Technische Universität München
Quellen
• „LINQ Im Einsatz“ – Manning – ISBN: 978-3-446-41429-7
• „Datenbank-Programmierung mit Microsoft LINQ“ – Microsoft Press – ISBN: 9978-3-86645-428
•  MSDN 17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
35
Technische Universität München
Danke
für‘s
Zuhören!
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
36
Technische Universität München
Anhang: Aktualisierungs-Anfrage
UPDATE [dbo].[Employees]
SET [OrderID] = @p4
WHERE ([EmployeeID] = @p0) AND ([FirstName] = @p1) AND ([LastName] = @p2)
AND ([OrderID] = @p3)
17.12.10
LINQ – Verstehen und Einsetzen
v. Georg Wagner
37
Herunterladen