1 Integrierte deklarative Abfragesprachen in imperativen Programmiersprachen am Beispiel von: Language INtegrated Query – LINQ Datenabfragen in C# Proseminar Programmierparadigmen und Sprachen Christian Piechnick SS 2009 Agenda 02 Agenda | Wozu | Was | Woher | Welche | Wie | Warum 1. Wozu LINQ ? 2. Was ist LINQ ? 3. Woher kommt LINQ ? 4. Welche Erweiterungen benötigt LINQ ? 5. Wie funktioniert LINQ ? 6. Warum LINQ / Warum Nicht? 01 Wozu LINQ ? 03 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Wie fragen wir normalerweise Daten ab ? Liefere mir eine Liste Ausgabeformat Von allen Webseiten der Welt Datenquelle die etwas mit LINQ zu tun haben Einschränkungen - deklarativ mengenorientiert 01 Wozu LINQ ? 04 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Abfragen von Datenbanken in SQL Syntax Liefere mir eine Liste Von allen Kunden Die mehr als 1000 € bezahlt haben SELECT C.* FROM Customers C WHERE ( SELECT SUM(Price) * SUM(Quantity) FROM Orders O WHERE O.CustID = C.CustID ) > 1000 01 Wozu LINQ ? 05 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Abfragen in imperativen Programmiersprachen Liefere mir eine Liste Von allen Kunden Die mehr als 1000 € bezahlt haben List<Customer> selectedCustomers = new List<Customer>(); foreach (Customer customer in context.getCustomers()) { int sum = 0; foreach (Order od in customer.Orders) { sum += od.UnitPrice * Quantity; } if(sum > 1000) selectedCustomers.Add(customer); } 01 Wozu LINQ ? 06 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Abfragen in LINQ var cust= from c in Customers where c.Orders.Sum(o => o.UnitPrice * o.Quantity) > 1000 select c; List<Customer> selectedCustomers = new List<Customer>(); foreach ( Customer customer in getCustomers() ) { int sum = 0; foreach (Order od in customer.Orders) { sum += od.UnitPrice * Quantity; } if(sum > 1000) selectedCustomers.Add(customer); } deklerativ imperativ 01 Wozu LINQ ? 07 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Wie gehen wir mit heterogenen Datenquellen um ? Objekte Datenbanken XML-Datein DBFramework XML Library Programmcode Web Services WS Library 02 Was ist LINQ ? 08 Agenda | Wozu | Was | Woher | Welche | Wie | Warum 02 Was ist LINQ ? 09 Agenda | Wozu | Was | Woher | Welche | Wie | Warum LINQ - Erweiterung des .NET Frameworks und Spracherweiterungen der .NET Sprachen Typsichere Abfragesprache auf Ebene der Programmiersprache SQL-ähnliche Syntax (Syntaxprüfung durch Compiler) Wählt den Ansatz der deklarativen Programmierung (High-Level) C# Visual Basic Andere Sprachen .NET Language Integrated Query (LINQ) .NET basierte Sprachen .NET Framework LINQ-fähige Datenquellen LINQ-fähiges ADO.NET LINQ to Objects LINQ to Dataset LINQ to SQL LINQ Provider LINQ to Entities LINQ to XML <Book> <author/> <Book> Datenquellen 02 Was ist LINQ ? 10 Agenda | Wozu | Was | Woher | Welche | Wie | Warum LINQ - Frameworkprovider LINQ to Objects LINQ to XML LINQ to SQL LINQ to ADO.NET LINQ to Entities arbeitet auf IEnumerable arbeitet auf XML Strukturen arbeitet auf dem Microsoft SQL Server arbeitet auf ADO.NET Datenquellen arbeitet auf beliebigen relativen Datenbanken LINQ – Weitere Provider LINQ to Amazon LINQ to NHibernate LINQ to Flickr LINQ to Google LINQ to LDAP … 03 Woher kommt LINQ ? 11 Agenda | Wozu | Was | Woher | Welche | Wie | Warum 03 Woher kommt LINQ ? 12 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Die .NET Plattform - .NET ist eine von Microsoft entwickelte Software-Plattform - 2002 erstmals veröffentlicht (zusammen mit Visual Studio als IDE) - .NET ist eine Implementierung der CLI (Common Language Infrastructure) - CLI ist ein ECMA Standard - soll sprach- und plattformunabhängige Entwicklung und Ausführung ermöglichen 03 Woher kommt LINQ ? 13 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Die .NET Plattform C# VB.NET C++ … C# Compiler VB.NET Compiler C++ Compiler … CLS Common Language Specification CIL Zwischencode Common Intermediate Language JIT Compiler für Windows JIT Compiler für anderes Betriebssystem Maschinencode Maschinencode CLR Common Language Runtime 04 Welche Erweiterungen benötigt LINQ ? 14 Agenda | Wozu | Was | Woher | Welche | Wie | Warum 04 Welche Erweiterungen benötigt LINQ ? 15 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Type Inference var var var var var name num num2 num3 cust = = = = = „Peter“; 25; 25.5; 25.5F; new Customer(); String int double float Customer - deklarieren von Variablen ohne explizite Angabe des Typs - implizites Ableiten des Typs durch Deklaration (strenge Typisierung) - Type Inference sollte nicht aus Faulheit benutzt werden Verwendung 1. Deklaration von Annonyme Typen 2. Zur Vermeidung von sehr langen Typen (Rückgabetypen von LINQ-Statements) 3. Umgang mit wechselnden Typen während der Entwicklung Was ist LINQ ? - Sprachgrundlagen Agenda | Wozu | Was | Woher | Welche | Wie | Warum Type Inference var name = „Peter“; String var var var var Integer Double Float Customer num num2 num3 cust = = = = 25; 25.5; 25.5F; new Customer(); C# Compiler 16 String name = „Peter“; int num = 25; double num2 = 25.5; float num3 = 25.5F; Customer cust = new Customer(); Pseudo CIL Was ist LINQ ? - Sprachgrundlagen 17 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Anonyme Typen var person = new { Name = „Peter“ } Console.WriteLine( person.Name ); - Klassen ohne vordefinierten Typ - besitzen nur lesbare Properties - Typ der Properties wird über Type Inference ermittelt - Anonyme Typen können nicht praktikabel als Parameter übergeben werden Verwendung - werden als temporäre Typen für kurze Verarbeitung genutzt 04 Welche Erweiterungen benötigt LINQ ? 18 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Extension Methods – Erweiterungsmethoden - Klassen statisch um Funktionalität erweitern - Methoden zu Klassen „hinzufügen“ ohne den Quellcode der Klasse zu manipulieren Konsequenzen - erhöht die Lesbarkeit des Quellcodes - ermöglicht Interfaces um Funktionalität zu erweitern 04 Welche Erweiterungen benötigt LINQ ? 19 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Extension Methods public static class MyExtensions { public static int Add(this int a, int b) { return a+b; } } int x = 12; int c = x.Add( 10 ); //c = 22 04 Welche Erweiterungen benötigt LINQ ? 20 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Extension Methods – „Erweiterung“ von Interfaces public interface ICatalog { void AddItem( String itemName ); … } public static class MyExtensions { public static void Sort(this ICatalog catalog) { //Implementierung der Sortierung } } 04 Welche Erweiterungen benötigt LINQ ? 21 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Wozu Extension Methods – Statische Helper-Klassen vs. Extension Methods Szenario: - Personen die einen Namen und ein Gehalt haben - Man braucht Filter die eine Liste von Personen nach Namen und Gehalt filtern List<Person> filterByName( List<Person> per, String name ) List<Person> filterBySalery( List<Person> per, int salery ) Mit Helper Klasse: MyHelper.filterByName( MyHelper.filterBySalery( persons,1000 ), „Peter ); Mit Extension Methods: persons.filterBySalery( 1000 ).filterByName( „Peter“ ); 04 Welche Erweiterungen benötigt LINQ ? 22 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Lambda Expressions Func<int, int, int> myFunction = (x,y) => x + y; myFunction(1,2); //3 - andere Syntax für „annonyme Methoden“ auf Basis von Funktionszeigern (delegates) - Annonyme Methoden und Delegates wurden mit .NET 2.0 eingeführt - Lambda Expressions sollen kürzere und besser lesbare Schreibweise darstellen - Parameters => Body - „=>“ ist der Lambda Operator - Func<int, int, int> symbolisiert eine Funktion, die 2 int Objekte als Eingabe auf ein int Objekt abbildet 04 Welche Erweiterungen benötigt LINQ ? 23 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Lambda Expressions – High Order Functions Func<int, bool> greaterTwo = x => x > 2; Func< Func<int,bool>, int, int > myFunction = (f, x) => f(x) ? x + 1 : 1; myFunc( greaterTwo, 1 ); myFunc( greaterTwo, 2 ); // 2 // 1 - Methoden die andere Methoden als Eingabewerte haben - Über Funktionszeiger (delegates) ist es möglich Methoden als Parameter zu übergeben - strenge Typisierung über Generics 04 Welche Erweiterungen benötigt LINQ ? 24 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Expression Trees - Expression Trees überführen ausführbaren Code in „Daten“ - Expression ist ein DOM für abstract syntax trees - Expression Trees sehen diesen Baum als Daten Expression Trees sind kein ausführbarer Code - können mit der Methode Compile() zur Laufzeit in ausführbaren Code überführt werden 04 Welche Erweiterungen benötigt LINQ ? 25 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Expression Trees Expr< Func< int, int, int > > myExpression = (x,y) => x + y; Expression Parameters x y Body – Binary Expression Left Parameter Expression x Right Node Type: Add Parameter Expression y 05 Wie funktioniert LINQ ? 26 Agenda | Wozu | Was | Woher | Welche | Wie | Warum 05 Wie funktioniert LINQ ? 27 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Operatoren - jede Abfrage beginnt mit: from element in LINQ-fähige-Datenquelle Restriction Where Projection Select, SelectMany Ordering OrderBy, ThenBy Grouping GroupBy Quantifiers Any, All Paritioning Take, Skip, TakeWhile, SkipWhile Sets Distinct, Union, Intersect, Except Elements First, FirstOrDefault, ElementAt Aggregation Count, Sum, Min, Max, Average Conversion ToArray, ToList, ToDictionary 05 Was ist LINQ ? - Sprachgrundlagen 28 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Ergebnisberchnung - Datenquelle und select geben an welchen Typ das Ergebnis hat LINQ-to-Objects LINQ-to-XML in-memory IEnumerable LINQ-to-SQL LINQ-to-Entities LINQ-to-Dataset delegiert IQueryable Delegates ExpressionTree 05 Wie funktioniert LINQ ? 29 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Ergebnisberchnung mit IQueryable - Bei einer delegierten LINQ-Abfrage wird ein Objekt des Typs IQueryable zurückgegeben - IQueryable repräsentiert den ExpressionTree der Anfrage mit zusätzlichen Informationen - erst wenn man mit dem Resultat arbeitet wird der Expression Tree in ausführbaren Code übersetzt und die Anfrage ausgeführt var query = from entry in dbcontext.Addressbook where entry.Lastname.StartsWith( „P“ ) select entry; PrintValues( query ); //Hans Pech, Max Proll dbcontext.Addressbook.Add( new Entry( „Lisa“, “Pech“ ); PrintValues( query ); //Hans Pech, Max Proll, Lisa Pech 05 Wie funktioniert LINQ ? 30 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Abfragetransformation - LINQ Keywords sind keine reservierten Keywords sondern kontextuell Keywords - Jedes LINQ Keyword hat eine äquivalente ExtensionMethod - Jede LINQ-Abfrage ist in eine äquivalente Form mit ExtensionMethods überführbar var query = from customer in Customers where customer.Name.startsWith(„A“) select customer; var query = Customers.Where( c => c.Name.startsWith(„A“) ).Select( c => c ); static IEnumerable<T> Where( this IEnumerable<T> source, Func<T,bool> predicate ) 05 Wie funktioniert LINQ ? 31 Agenda | Wozu | Was | Woher | Welche | Wie | Warum var cust = from c in context.Customers where c.Name = „Peter“ select c; LINQ Statement var cust = context.Customers.Where( c => c.Name == „Peter“ ); Lambda Expression delegiert In-memory Anfragetransformation abstract syntax tree SELECT C.* FROM Customers C WHERE C.Name = „Peter“ Datenquellabhängige Anfrage 05 Wie funktioniert LINQ ? 32 Agenda | Wozu | Was | Woher | Welche | Wie | Warum PLINQ – Parallel Linq - deklarativer oder funktionaler Code lässt sich einfacher automatisch parallelisieren - PLINQ wird Teil des .NET Frameworks 4.0 sein - Parallelisieren der Anfrageausführung von in-memory-Datenquellen (Objects, XML etc.) var query = ( from customer in Customers where customer.Name.startsWith(„A“) select customer ).AsParallel(2); 06 Warum LINQ ? 33 Agenda | Wozu | Was | Woher | Welche | Wie | Warum Vorteile - Datenquellenunabhängige Abfragesprache - Vom Compiler lesbar (syntaktische Fehler werden zur Compile-/Entwicklungszeit erkannt) - Vom Entwickler lesbar (kürzerer und klarerer Quellcode) Nachteile - Erlernen einer „neuen Technologie“ - zum Teil bringen LINQ-Provider spezifische Technologien mit, die man verwenden muss - zur Zeit kann man in einer Query nur eine delegierende Datenquelle verwenden