SlideShare une entreprise Scribd logo
1  sur  41
Télécharger pour lire hors ligne
LINQ
Language INtegrated Query
        Giovanni Lagorio
      lagorio@disi.unige.it

   JUG Genova, 14 Luglio 2009
Licenza
Questi lucidi sono rilasciati sotto la licenza Creative Commons
  Attribuzione-Non commerciale-Non opere derivate 3.0
  Unported.
  Per leggere una copia della licenza visita il sito web
  http://creativecommons.org/licenses/by-nc-nd/3.0/ o
  spedisci una lettera a Creative Commons, 171 Second
  Street, Suite 300, San Francisco, California, 94105, USA.
In due parole, possono essere liberamente usati, copiati e
   distribuiti purché:
1. Venga citata la fonte originale
2. Non vengano usati in ambito commerciale
3. Non vengano modificati in nessun modo
Cosa vedremo?
• LINQ
  – Cos’è? Requisiti, pubblicità 
  – Accenni di cosa succede “dietro le quinte”
     • LINQ to Objects
     • LINQ to SQL
• Panoramica di ADO Entity Framework
• Conclusioni
Cos’è LINQ?
Uno strumento per interrogare in modo
 uniforme
  – Oggetti in memoria (LINQ to Objects)
  – Database relazionali (LINQ to SQL)
  – Documenti XML (LINQ to XML)
  – Modelli E/R (LINQ to Entities)
  – ...altro... LINQ to Flickr, LINQ to whatever 
LINQ non è ORM, ma è un’ottima interfaccia per
  interrogarli
Cos’ha di tanto speciale LINQ?
• Uniformità ed Estensibilità
• Query a livello di linguaggio
  – Type checking
  – Nell’IDE:
     • Intellisense
     • Refactoring
  – Non serve escaping 
    niente più (SQL) injection
Cosa serve?
• .NET 3.5/Visual Studio 2008
   – C# 3 C# 2 + “quello che serve per LINQ”
   – il risultato è compatibile con .NET 2.0
• Quindi, tutta “compiler magic”
   – type inference, quanto basta, e
   – zucchero sintattico come se piovesse 
• Quindi, è realistico che arrivi in Java
   – Java 6 = Java 5 C# 2
   – Per Java 7 si parla di closure...
LINQ to Objects
string[] strings = { "g", null, "gENoVa", "jug" };

var query = from s in strings
        where s.Length>2
        orderby s descending
        select s.ToUpper();

var query2 = from s in query
         where s.StartsWith("G")
         select s.Length;

strings[1] = "a";
                                                     Sum=6
int sum = query2.Sum();

Console.WriteLine("Sum={0}n", sum);
                                                       JUG
foreach (string s in query) Console.WriteLine(s);    GENOVA
Var
• Solo per dichiarare variabili locali, il tipo (inferito) è
  quello dell’inizializzatore
• Esempio:
  int i = 0;
  var i = 0; // equivalenti, finché non cambia inizializz.
• E’ chiaramente molto comoda con i generici...
  List<List<string>> lls =
           new List<List<string>>();
  var lls = new List<List<string>>();
• Non solo per i pigri, essenziale in alcuni casi
LINQ to SQL
using (var context = new JUGDataContext()) {
   var q = from user in context.Users
         where user.lastname.Length>1
         select user;
   q = from user in q
      orderby user.lastname
      select user;
   foreach (var x in q) // esegue una DB query
         Console.WriteLine(x.lastname + " " +
                               x.firstname);
}
ToList/ToArray
var q = from user in context.Users
       orderby user.lastname
       select user;
// esegue 10 volte la query
for (int a = 0; a < 10; ++a)
   foreach (var x in q) // ...

List<User> l = q.ToList();
// esegue una sola volta sul DB
for (int a = 0; a < 10; ++a)
   foreach (var x in l) // ...
Proiezioni e Tipi anonimi
var q = from user in context.Users
      orderby user.lastname
      select new { user.firstname, user.lastname,
              fullName = user.firstname+" "+user.lastname } ;
foreach (var x in q)
 Console.WriteLine("nome={0}, cognome={1}, nome
   completo={2}", x.firstname, x.lastname, x.fullName);

Qui var diventa obbligatorio! Che tipo ha x?
Un tipo anonimo, sappiamo solo che ha un campo firstname di
  tipo string, ecc.
Scorciatoie varie...
var   array = new[] { "ciao", "mondo" };
var   anA = new A(3) { G=3 };
var   anotherA = new A { F=5, G=3 };
var   something = new { Answer = 42 };

Nei primi tre casi, al posto di var avrei
 potuto usare: string [], A e A
Esempio con groupby
string[] strings = { "Gio", "Java", "Genova", "JUG", "Zorro" };

var query = from s in strings
    group s by s[0] into sameFirstLGroup
    orderby sameFirstLGroup.Count() ascending       FirstLetter = Z
    select new { FirstLetter = sameFirstLGroup.Key, Words =
                      Words = sameFirstLGroup };         Zorro
                                                    FirstLetter = G
foreach (var g in query) {                          Words =
   Console.WriteLine("FirstLetter = {0}",                Gio
                              g.FirstLetter);            Genova
   Console.WriteLine("Words = ");                   FirstLetter = J
   foreach (var w in g.Words)                       Words =
      Console.WriteLine("t{0}", w);                     Java
}                                                        JUG
Altro zucchero sintattico...
var ls = new List<string>()
              { "qui", "quo", "qua" };
var d = new Dictionary<int, string>()
     { { 1, "pippo" }, { 2, "pluto" } };

Auto-implemented properties:
 int pippo { get; set; }
Cos’è davvero una query?
• Qualcosa che “trasforma” una sequenza in un’altra
  – string[] strings = { "qui", "quo", "qua" };
    var q = from s in strings select s.Length;
• Ok…cos’è una sequenza?
  – tutte le “robe foreach-abili”: IEnumerable<T>
Sequenze di “cosi”
• IEnumerable<T>                       • java.lang.Iterable<T>
   – IEnumerator<T>                       – Iterator<T>
     GetEnumerator()                        iterator()
• IEnumerator<T>                       • java.lang.Iterator<T>
   – bool MoveNext()                      – hasNext()
   – T Current { get; }                   – next()
   – (... Reset e Dispose che non ci      – (... e remove che non ci
     interessano)                           interessa)

                                             ...
Esempi
Se il risultato è una sequenza di oggetti di tipo R, il tipo della
  query sarà IEnumerable<R>
• string[] strings = {"qui", "quo", "qua"};
  IEnumerable<int> q1 = from s in strings
                            select s.Length;
• IEnumerable<string> q2 = from s in strings select s;
• IEnumerable<string> q3 = strings;
• IEnumerable<bool> q4 = from i in
                      (from s in strings select s.Length)
                      select i > 0;
Troppa magia... come funziona?!?
var q = from user in
            /* un certo IEnumerable<User> */
      where user.firstname == "Giovanni"
      select user;
foreach (var x in q)
   Console.WriteLine(x.firstname);

Come può generare il codice corretto?!? La
  condizione deve diventare del codice .NET, una
  clausola WHERE in SQL o che altro?
Dipende dal provider... che non conosciamo!
C’è il trucco ;-)
1. Esiste una traduzione che trasforma le query LINQ
   in una serie di chiamate di metodo
  – Traduzione puramente sintattica: il risultato viene poi
    compilato con le regole usuali
2. La sorgente può essere più specifica di quanto
   detto prima, per esempio:
   interface IQueryable<T> : IEnumerable<T>, ...
   rappresenta, terminologia mia, le sequenze
   “LINQ-aware”
Versione tradotta,
       senza “zucchero sintattico”
var q = /* ... un IEnumerable/IQueryable ... */
      .Where(user => user.firstname == "Giovanni")
      .Select(user => user);

Ora sì che va meglio! Al posto di un problema ne
  abbiamo due 
1. Cosa sono Where e Select? Sembrano metodi ma
   non fanno parte di IEnumerable...
2. Cosa gli passiamo?
Extension methods
• E’ possibile aggiungere metodi
  (implementati) a una qualunque
  classe/interfaccia
• Visti dall’intellisense (quasi)
  come gli altri
• Meccanismo molto potente,
  ricorda l’Aspect Oriented
  Programming
  – sembra fin troppo facile abusarne
Extension methods: come?
• Si usa this come modificatore del primo
  parametro di un metodo statico
  public static int m(this T x, int k, ...)
• Il compilatore trasforma le chiamate
  expr.m(1, 2, 3)
  dove expr ha tipo T (e non c’è nessun metodo
  migliore) in:
  MiaClasseStatica.MioExtMethod(expr, 1, 2, 3)
Esempio di estensione
            (totalmente inutile)
public static class MyStringExtension {
    public static int TwiceLength(this string s) {
       return s.Length * 2;
    }
}
 ...
Console.WriteLine("ciao".TwiceLength());
   // stampa 8, trasformata dal compilatore in:
Console.WriteLine(MyStringExtension.
                          TwiceLength("ciao"));
Lambda Expressions (Closures)
• Fanno finta di essere λ-astrazioni del λ-calcolo ,
  ovvero definizioni di funzioni “inline”
  Esempi:
   – (int x, int y) => x + y
     rappresenta la funzione che somma x e y
   – a => a * a
     rappresenta la funzione quadrato
   – (x, y) => { if (x < y) return x; else return y; }
     rappresenta la funzione che restituisce il minimo
• Il tipo dei parametri può essere inferito
   – Se il parametro è uno solo, non servono le parentesi
Lambda Expression (cont.)
Una lambda-expression è, di per sé, totalmente
  inutile (!) ma può essere convertita in:
• un delegate, in sostanza, in codice .NET che
  valuta la funzione, oppure in
• un Expression tree, (codice .NET che costruisce)
  una struttura dati che rappresenta l’espressione,
  che il provider trasformerà in una qualche forma
  più furba per l’esecuzione (per esempio, una
  query SQL per un DB relazionale)
Esempio expression tree
Riprendiamo la versione “dietetica”
var q = /* ... */
      .Where(user => user.firstname == "Giovanni")
      .Select(user => user);

In base al tipo della sorgente:
public static IEnumerable<T> Where<T>(
  this IEnumerable<T> source,
  Func<T, bool> predicate)
public static IQueryable<T> Where<T>(
   this IQueryable<T> source,
   Expression<Func<T, bool>> predicate)
Ma allora, cosa devo usare?
            IEnumerable<T>

             IQueryable<T>

Dipende, comunque un IEnumerable si
 converte facilmente con asQueryable

Non è (sempre) un cast:
int[] ints = { 1, 2, 3 };
IQueryable<int> iq = ints.AsQueryable();
Limiti dell’approccio
• Alcune espressioni possibili solo con LINQ to
  Objects, per esempio in LINQ to SQL:
  var q = from user in context.Users
          where user.MyMethod()>0 /* boom */
          select user.MyMethod() /* ok */ ;
   – Comunque, molti (tutti?) metodi standard di
     numeri/stringhe/date vengono tradotti
• Mi sembra sconsigliabile, ma limitandosi a LINQ
  to Objects è possibile modificare gli oggetti
  visitati
ADO ENTITIES FRAMEWORK
ADO Entities Framework
• E’ un ORM, al di là di quello che sostiene M$
• Permette di lavorare a livello di Modello E/R
  (ereditarietà, relazioni molti-a-molti, ...)
• Si può interrogare via:
  – Entities SQL (SQL), per esempio:
    SELECT VALUE c FROM E.Contacts AS c
    WHERE c.FirstName='Pippo'
  – LINQ to Entities
    La sintassi è quella che vi aspettate
Mapping
• Descritto da tre file XML
  – Ma VS li nasconde abbastanza
              Modello                                  Store
             Concettuale             Mapping
                                                      Schema
                (E/R)                 .MSL
                                        Mapping        .SSDL
               .CSDL                  Specification
                                       Language
                                                      Store Schema
                                                        Definition
              Conceptual Schema                         Language
              Definition Language

                                                                      (tipicamente)
                                                                         DB
   Oggetti                                                           Relazionale
Esempio: Entities vs DB Schema
EntityContext
Dai file XML otteniamo:
• Le classi (parziali) corrispondenti ai tipi entità
• Una classe QualcosaEntityContext (che
  estende ObjectContext) che ci permette di
  dialogare con il modello, tramite:
   – proprietà che corrispondono agli insiemi entità
   – metodi AddTo
Il contesto materializza gli oggetti e traccia i
   cambiamenti, salvati con SaveChanges
Esempio di inserimento dati
using (var context = new JUGEntities()) {
   User u = new User() { username = "Gio",
                     firstname="g", lastname="l" };
   Role r = new Role() { rolename = "Admin" };
   u.Roles.Add(r);
   Document d = new ToDo() { Author = u,
                     title = "demo", what="boh" };
   context.AddToDocuments(d);
   context.SaveChanges();
   // tutti gli oggetti vengono salvati e
   // l'ordine delle insert e` automatico
}
Esempio di interrogazione
using (var context = new JUGEntities()) {
   var q = from d in context.Documents.Include("Author.Roles")
         where d.Author.username=="Gio"
         select d;
   var aDoc = q.First();
   //aDoc.AuthorReference.Load();
   User author = aDoc.Author;
   Console.WriteLine("Author: {0}nRoles:", author.firstname);
   //author.Roles.Load();
   foreach (Role r in author.Roles)
      Console.WriteLine("t{0}", r.rolename);
}
Esempio di modifica/cancellazione

using (var context = new JUGEntities()) {
   var todos = (from d in context.Documents.OfType<ToDo>()
         select d).ToArray();

    context.DeleteObject(todos[0]);

    todos[1].what = "blabla";

    context.SaveChanges();
}
LINQ to SQL vs LINQ to Entities
Visto che, alla fin fine, si parla di DB relazionali,
  un confronto è inevitabile.

Alcune domande abbastanza ovvie sono:
• LINQ to SQL è un ORM?
• Quanto si assomigliano?
• Posso passare dall’uno all’altro con facilità?
LINQ to...               SQL                            Entities
E’ un ORM                No                             Sì
Cosa si “vede”?          Delle tabelle, relazioni 1-n   Entità e Relazioni (anche n-m)

Ereditarietà             No (sì ma...)                  Sì
Transazioni              No (ma basta wrappare in       Si (su DB singolo, se non basta:
                         ScopeTransaction)              ScopeTransaction)
Query SQL generate       Ragionevoli                    A volte ragionevoli
Da modello a DB e        No (ma avrebbe senso?)         Solo da VS 2010, purtroppo
viceversa?
Sincronizzazione         No (mi sembra, VS2010?),       Sì
schema DB?               non grave: classi parziali
Editor Visuale           Sì                             Sì al 90% (speriamo in VS
                                                        2010...)
Lazy/eager loading       Per context/implicito          Per query/esplicito

Locking ottimistico      Di default su tutto            Sì, ma di default su nulla

Single/SingleOrDefault   Sì                             No! (Eccezione a runtime)
Conclusioni
• Oggi: LINQ to
  –   Objects: molto comodo
  –   XML: esiste, non l’ho mai usato
  –   SQL: ok, ma alle “ORMeggia”  a sproposito
  –   Entities: interessante, probabilmente immaturo
• Domani?
  – LINQ in Java?
  – LINQ to (N)Hibernate: abbastanza non-m$ per essere
    apprezzato da tutti?
  – PLINQ, un .AsParallel() rende la query parallela!
Grazie per l’attenzione

   ...domande?

Contenu connexe

Tendances (20)

Corso c++
Corso c++Corso c++
Corso c++
 
2006 Py03 intermedio
2006 Py03 intermedio2006 Py03 intermedio
2006 Py03 intermedio
 
Two months of Kotlin
Two months of KotlinTwo months of Kotlin
Two months of Kotlin
 
Presentazione Oz - Mozart
Presentazione Oz - MozartPresentazione Oz - Mozart
Presentazione Oz - Mozart
 
Java5
Java5Java5
Java5
 
Ruby in 25 minuti
Ruby in 25 minutiRuby in 25 minuti
Ruby in 25 minuti
 
2011.02.19 Introducing F#
2011.02.19 Introducing F#2011.02.19 Introducing F#
2011.02.19 Introducing F#
 
C# Language Evolution
C# Language EvolutionC# Language Evolution
C# Language Evolution
 
Dal C a Java (1/3)
Dal C a Java (1/3)Dal C a Java (1/3)
Dal C a Java (1/3)
 
Stringhe java
Stringhe javaStringhe java
Stringhe java
 
Dal C a Java (2/3)
Dal C a Java (2/3)Dal C a Java (2/3)
Dal C a Java (2/3)
 
Dal c a Java (3/3)
Dal c a Java (3/3)Dal c a Java (3/3)
Dal c a Java (3/3)
 
Java 8
Java 8Java 8
Java 8
 
Java 8: le nuove-interfacce di Ezio Sperduto
Java 8: le nuove-interfacce di Ezio SperdutoJava 8: le nuove-interfacce di Ezio Sperduto
Java 8: le nuove-interfacce di Ezio Sperduto
 
Programmazione concorrente in Java (vecchio modello)
Programmazione concorrente in Java (vecchio modello)Programmazione concorrente in Java (vecchio modello)
Programmazione concorrente in Java (vecchio modello)
 
esempio open closed
esempio open closedesempio open closed
esempio open closed
 
Pycrashcourse3.1
Pycrashcourse3.1Pycrashcourse3.1
Pycrashcourse3.1
 
iContract
iContractiContract
iContract
 
Il simulatore NS-2
Il simulatore NS-2Il simulatore NS-2
Il simulatore NS-2
 
May 2010 - Hibernate search
May 2010 - Hibernate searchMay 2010 - Hibernate search
May 2010 - Hibernate search
 

En vedette

C# Chat for Windows: Network infrastructure + file sharing + clipboard sharin...
C# Chat for Windows: Network infrastructure + file sharing + clipboard sharin...C# Chat for Windows: Network infrastructure + file sharing + clipboard sharin...
C# Chat for Windows: Network infrastructure + file sharing + clipboard sharin...Francesco Corazza
 
Server Day 2009: Spring dm Server by Alef Arendsen
Server Day 2009: Spring dm Server by Alef ArendsenServer Day 2009: Spring dm Server by Alef Arendsen
Server Day 2009: Spring dm Server by Alef ArendsenJUG Genova
 
Introduction to C#
Introduction to C#Introduction to C#
Introduction to C#Guido Magrin
 
Playing with parse.com
Playing with parse.comPlaying with parse.com
Playing with parse.comJUG Genova
 
Java 9 by Alessio Stalla
Java 9 by Alessio StallaJava 9 by Alessio Stalla
Java 9 by Alessio StallaJUG Genova
 

En vedette (6)

C# Chat for Windows: Network infrastructure + file sharing + clipboard sharin...
C# Chat for Windows: Network infrastructure + file sharing + clipboard sharin...C# Chat for Windows: Network infrastructure + file sharing + clipboard sharin...
C# Chat for Windows: Network infrastructure + file sharing + clipboard sharin...
 
Server Day 2009: Spring dm Server by Alef Arendsen
Server Day 2009: Spring dm Server by Alef ArendsenServer Day 2009: Spring dm Server by Alef Arendsen
Server Day 2009: Spring dm Server by Alef Arendsen
 
Introduction to C#
Introduction to C#Introduction to C#
Introduction to C#
 
Playing with parse.com
Playing with parse.comPlaying with parse.com
Playing with parse.com
 
JMeter
JMeterJMeter
JMeter
 
Java 9 by Alessio Stalla
Java 9 by Alessio StallaJava 9 by Alessio Stalla
Java 9 by Alessio Stalla
 

Similaire à LINQ, Entities Framework & ORMs

Similaire à LINQ, Entities Framework & ORMs (20)

Functional Programming in Java - Le Espressioni Lambda
Functional Programming in Java - Le Espressioni LambdaFunctional Programming in Java - Le Espressioni Lambda
Functional Programming in Java - Le Espressioni Lambda
 
Riepilogo Java C/C++
Riepilogo Java C/C++Riepilogo Java C/C++
Riepilogo Java C/C++
 
Introduzione a node.js
Introduzione a node.jsIntroduzione a node.js
Introduzione a node.js
 
Introduzione a Node.js
Introduzione a Node.jsIntroduzione a Node.js
Introduzione a Node.js
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
 
What's new in C# 7
What's new in C# 7What's new in C# 7
What's new in C# 7
 
Mini Corso Java - Parte 1
Mini Corso Java - Parte 1Mini Corso Java - Parte 1
Mini Corso Java - Parte 1
 
Scala Programming Linux Day 2009
Scala Programming Linux Day 2009Scala Programming Linux Day 2009
Scala Programming Linux Day 2009
 
Javaday 2006: Java 5
Javaday 2006: Java 5Javaday 2006: Java 5
Javaday 2006: Java 5
 
What is new in C# 2018
What is new in C# 2018What is new in C# 2018
What is new in C# 2018
 
Vb.Net
Vb.NetVb.Net
Vb.Net
 
A brief intro to TDD for a JUG-TAA event
A brief intro to TDD for a JUG-TAA eventA brief intro to TDD for a JUG-TAA event
A brief intro to TDD for a JUG-TAA event
 
Groovy e Domain Specific Languages
Groovy e Domain Specific LanguagesGroovy e Domain Specific Languages
Groovy e Domain Specific Languages
 
Rest sdk
Rest sdkRest sdk
Rest sdk
 
Acadevmy - TypeScript Overview
Acadevmy - TypeScript OverviewAcadevmy - TypeScript Overview
Acadevmy - TypeScript Overview
 
Java codestyle & tipstricks
Java codestyle & tipstricksJava codestyle & tipstricks
Java codestyle & tipstricks
 
Primo Incontro Con Scala
Primo Incontro Con ScalaPrimo Incontro Con Scala
Primo Incontro Con Scala
 
Pycon
PyconPycon
Pycon
 
Webbit 2004: Tiger, java
Webbit 2004: Tiger, javaWebbit 2004: Tiger, java
Webbit 2004: Tiger, java
 
lezione1.pdf
lezione1.pdflezione1.pdf
lezione1.pdf
 

Plus de JUG Genova

Lcds & Blaze Ds by Corneliu Creanga
Lcds & Blaze Ds by Corneliu CreangaLcds & Blaze Ds by Corneliu Creanga
Lcds & Blaze Ds by Corneliu CreangaJUG Genova
 
Flex Air Intro
Flex Air IntroFlex Air Intro
Flex Air IntroJUG Genova
 
Server Day 2009: Oracle/Bea Fusion Middleware by Paolo Ramasso
Server Day 2009: Oracle/Bea Fusion Middleware by Paolo RamassoServer Day 2009: Oracle/Bea Fusion Middleware by Paolo Ramasso
Server Day 2009: Oracle/Bea Fusion Middleware by Paolo RamassoJUG Genova
 
Server Day 2009: GlassFish 3 by Alexis Moussine-Pouchkine
Server Day 2009: GlassFish 3 by Alexis Moussine-PouchkineServer Day 2009: GlassFish 3 by Alexis Moussine-Pouchkine
Server Day 2009: GlassFish 3 by Alexis Moussine-PouchkineJUG Genova
 
Server Day 2009: JBoss 5.0 by Alessio Soldano
Server Day 2009: JBoss 5.0 by Alessio SoldanoServer Day 2009: JBoss 5.0 by Alessio Soldano
Server Day 2009: JBoss 5.0 by Alessio SoldanoJUG Genova
 
Java IDE Day 2008 - Introduction by JUG Genova
Java IDE Day 2008 - Introduction by JUG GenovaJava IDE Day 2008 - Introduction by JUG Genova
Java IDE Day 2008 - Introduction by JUG GenovaJUG Genova
 
Java Ide Day 2008 - Presentation on JDeveloper by Paolo Ramasso
Java Ide Day 2008 - Presentation on JDeveloper by Paolo RamassoJava Ide Day 2008 - Presentation on JDeveloper by Paolo Ramasso
Java Ide Day 2008 - Presentation on JDeveloper by Paolo RamassoJUG Genova
 
Java Ide Day 2008 - Presentation on Intelli J Idea by Vaclav Pech
Java Ide Day 2008 - Presentation on Intelli J Idea by Vaclav PechJava Ide Day 2008 - Presentation on Intelli J Idea by Vaclav Pech
Java Ide Day 2008 - Presentation on Intelli J Idea by Vaclav PechJUG Genova
 

Plus de JUG Genova (8)

Lcds & Blaze Ds by Corneliu Creanga
Lcds & Blaze Ds by Corneliu CreangaLcds & Blaze Ds by Corneliu Creanga
Lcds & Blaze Ds by Corneliu Creanga
 
Flex Air Intro
Flex Air IntroFlex Air Intro
Flex Air Intro
 
Server Day 2009: Oracle/Bea Fusion Middleware by Paolo Ramasso
Server Day 2009: Oracle/Bea Fusion Middleware by Paolo RamassoServer Day 2009: Oracle/Bea Fusion Middleware by Paolo Ramasso
Server Day 2009: Oracle/Bea Fusion Middleware by Paolo Ramasso
 
Server Day 2009: GlassFish 3 by Alexis Moussine-Pouchkine
Server Day 2009: GlassFish 3 by Alexis Moussine-PouchkineServer Day 2009: GlassFish 3 by Alexis Moussine-Pouchkine
Server Day 2009: GlassFish 3 by Alexis Moussine-Pouchkine
 
Server Day 2009: JBoss 5.0 by Alessio Soldano
Server Day 2009: JBoss 5.0 by Alessio SoldanoServer Day 2009: JBoss 5.0 by Alessio Soldano
Server Day 2009: JBoss 5.0 by Alessio Soldano
 
Java IDE Day 2008 - Introduction by JUG Genova
Java IDE Day 2008 - Introduction by JUG GenovaJava IDE Day 2008 - Introduction by JUG Genova
Java IDE Day 2008 - Introduction by JUG Genova
 
Java Ide Day 2008 - Presentation on JDeveloper by Paolo Ramasso
Java Ide Day 2008 - Presentation on JDeveloper by Paolo RamassoJava Ide Day 2008 - Presentation on JDeveloper by Paolo Ramasso
Java Ide Day 2008 - Presentation on JDeveloper by Paolo Ramasso
 
Java Ide Day 2008 - Presentation on Intelli J Idea by Vaclav Pech
Java Ide Day 2008 - Presentation on Intelli J Idea by Vaclav PechJava Ide Day 2008 - Presentation on Intelli J Idea by Vaclav Pech
Java Ide Day 2008 - Presentation on Intelli J Idea by Vaclav Pech
 

LINQ, Entities Framework & ORMs

  • 1. LINQ Language INtegrated Query Giovanni Lagorio lagorio@disi.unige.it JUG Genova, 14 Luglio 2009
  • 2. Licenza Questi lucidi sono rilasciati sotto la licenza Creative Commons Attribuzione-Non commerciale-Non opere derivate 3.0 Unported. Per leggere una copia della licenza visita il sito web http://creativecommons.org/licenses/by-nc-nd/3.0/ o spedisci una lettera a Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. In due parole, possono essere liberamente usati, copiati e distribuiti purché: 1. Venga citata la fonte originale 2. Non vengano usati in ambito commerciale 3. Non vengano modificati in nessun modo
  • 3. Cosa vedremo? • LINQ – Cos’è? Requisiti, pubblicità  – Accenni di cosa succede “dietro le quinte” • LINQ to Objects • LINQ to SQL • Panoramica di ADO Entity Framework • Conclusioni
  • 4. Cos’è LINQ? Uno strumento per interrogare in modo uniforme – Oggetti in memoria (LINQ to Objects) – Database relazionali (LINQ to SQL) – Documenti XML (LINQ to XML) – Modelli E/R (LINQ to Entities) – ...altro... LINQ to Flickr, LINQ to whatever  LINQ non è ORM, ma è un’ottima interfaccia per interrogarli
  • 5. Cos’ha di tanto speciale LINQ? • Uniformità ed Estensibilità • Query a livello di linguaggio – Type checking – Nell’IDE: • Intellisense • Refactoring – Non serve escaping  niente più (SQL) injection
  • 6. Cosa serve? • .NET 3.5/Visual Studio 2008 – C# 3 C# 2 + “quello che serve per LINQ” – il risultato è compatibile con .NET 2.0 • Quindi, tutta “compiler magic” – type inference, quanto basta, e – zucchero sintattico come se piovesse  • Quindi, è realistico che arrivi in Java – Java 6 = Java 5 C# 2 – Per Java 7 si parla di closure...
  • 7. LINQ to Objects string[] strings = { "g", null, "gENoVa", "jug" }; var query = from s in strings where s.Length>2 orderby s descending select s.ToUpper(); var query2 = from s in query where s.StartsWith("G") select s.Length; strings[1] = "a"; Sum=6 int sum = query2.Sum(); Console.WriteLine("Sum={0}n", sum); JUG foreach (string s in query) Console.WriteLine(s); GENOVA
  • 8. Var • Solo per dichiarare variabili locali, il tipo (inferito) è quello dell’inizializzatore • Esempio: int i = 0; var i = 0; // equivalenti, finché non cambia inizializz. • E’ chiaramente molto comoda con i generici... List<List<string>> lls = new List<List<string>>(); var lls = new List<List<string>>(); • Non solo per i pigri, essenziale in alcuni casi
  • 9. LINQ to SQL using (var context = new JUGDataContext()) { var q = from user in context.Users where user.lastname.Length>1 select user; q = from user in q orderby user.lastname select user; foreach (var x in q) // esegue una DB query Console.WriteLine(x.lastname + " " + x.firstname); }
  • 10. ToList/ToArray var q = from user in context.Users orderby user.lastname select user; // esegue 10 volte la query for (int a = 0; a < 10; ++a) foreach (var x in q) // ... List<User> l = q.ToList(); // esegue una sola volta sul DB for (int a = 0; a < 10; ++a) foreach (var x in l) // ...
  • 11. Proiezioni e Tipi anonimi var q = from user in context.Users orderby user.lastname select new { user.firstname, user.lastname, fullName = user.firstname+" "+user.lastname } ; foreach (var x in q) Console.WriteLine("nome={0}, cognome={1}, nome completo={2}", x.firstname, x.lastname, x.fullName); Qui var diventa obbligatorio! Che tipo ha x? Un tipo anonimo, sappiamo solo che ha un campo firstname di tipo string, ecc.
  • 12. Scorciatoie varie... var array = new[] { "ciao", "mondo" }; var anA = new A(3) { G=3 }; var anotherA = new A { F=5, G=3 }; var something = new { Answer = 42 }; Nei primi tre casi, al posto di var avrei potuto usare: string [], A e A
  • 13. Esempio con groupby string[] strings = { "Gio", "Java", "Genova", "JUG", "Zorro" }; var query = from s in strings group s by s[0] into sameFirstLGroup orderby sameFirstLGroup.Count() ascending FirstLetter = Z select new { FirstLetter = sameFirstLGroup.Key, Words = Words = sameFirstLGroup }; Zorro FirstLetter = G foreach (var g in query) { Words = Console.WriteLine("FirstLetter = {0}", Gio g.FirstLetter); Genova Console.WriteLine("Words = "); FirstLetter = J foreach (var w in g.Words) Words = Console.WriteLine("t{0}", w); Java } JUG
  • 14. Altro zucchero sintattico... var ls = new List<string>() { "qui", "quo", "qua" }; var d = new Dictionary<int, string>() { { 1, "pippo" }, { 2, "pluto" } }; Auto-implemented properties: int pippo { get; set; }
  • 15. Cos’è davvero una query? • Qualcosa che “trasforma” una sequenza in un’altra – string[] strings = { "qui", "quo", "qua" }; var q = from s in strings select s.Length; • Ok…cos’è una sequenza? – tutte le “robe foreach-abili”: IEnumerable<T>
  • 16. Sequenze di “cosi” • IEnumerable<T> • java.lang.Iterable<T> – IEnumerator<T> – Iterator<T> GetEnumerator() iterator() • IEnumerator<T> • java.lang.Iterator<T> – bool MoveNext() – hasNext() – T Current { get; } – next() – (... Reset e Dispose che non ci – (... e remove che non ci interessano) interessa) ...
  • 17. Esempi Se il risultato è una sequenza di oggetti di tipo R, il tipo della query sarà IEnumerable<R> • string[] strings = {"qui", "quo", "qua"}; IEnumerable<int> q1 = from s in strings select s.Length; • IEnumerable<string> q2 = from s in strings select s; • IEnumerable<string> q3 = strings; • IEnumerable<bool> q4 = from i in (from s in strings select s.Length) select i > 0;
  • 18. Troppa magia... come funziona?!? var q = from user in /* un certo IEnumerable<User> */ where user.firstname == "Giovanni" select user; foreach (var x in q) Console.WriteLine(x.firstname); Come può generare il codice corretto?!? La condizione deve diventare del codice .NET, una clausola WHERE in SQL o che altro? Dipende dal provider... che non conosciamo!
  • 19. C’è il trucco ;-) 1. Esiste una traduzione che trasforma le query LINQ in una serie di chiamate di metodo – Traduzione puramente sintattica: il risultato viene poi compilato con le regole usuali 2. La sorgente può essere più specifica di quanto detto prima, per esempio: interface IQueryable<T> : IEnumerable<T>, ... rappresenta, terminologia mia, le sequenze “LINQ-aware”
  • 20. Versione tradotta, senza “zucchero sintattico” var q = /* ... un IEnumerable/IQueryable ... */ .Where(user => user.firstname == "Giovanni") .Select(user => user); Ora sì che va meglio! Al posto di un problema ne abbiamo due  1. Cosa sono Where e Select? Sembrano metodi ma non fanno parte di IEnumerable... 2. Cosa gli passiamo?
  • 21. Extension methods • E’ possibile aggiungere metodi (implementati) a una qualunque classe/interfaccia • Visti dall’intellisense (quasi) come gli altri • Meccanismo molto potente, ricorda l’Aspect Oriented Programming – sembra fin troppo facile abusarne
  • 22. Extension methods: come? • Si usa this come modificatore del primo parametro di un metodo statico public static int m(this T x, int k, ...) • Il compilatore trasforma le chiamate expr.m(1, 2, 3) dove expr ha tipo T (e non c’è nessun metodo migliore) in: MiaClasseStatica.MioExtMethod(expr, 1, 2, 3)
  • 23. Esempio di estensione (totalmente inutile) public static class MyStringExtension { public static int TwiceLength(this string s) { return s.Length * 2; } } ... Console.WriteLine("ciao".TwiceLength()); // stampa 8, trasformata dal compilatore in: Console.WriteLine(MyStringExtension. TwiceLength("ciao"));
  • 24. Lambda Expressions (Closures) • Fanno finta di essere λ-astrazioni del λ-calcolo , ovvero definizioni di funzioni “inline” Esempi: – (int x, int y) => x + y rappresenta la funzione che somma x e y – a => a * a rappresenta la funzione quadrato – (x, y) => { if (x < y) return x; else return y; } rappresenta la funzione che restituisce il minimo • Il tipo dei parametri può essere inferito – Se il parametro è uno solo, non servono le parentesi
  • 25. Lambda Expression (cont.) Una lambda-expression è, di per sé, totalmente inutile (!) ma può essere convertita in: • un delegate, in sostanza, in codice .NET che valuta la funzione, oppure in • un Expression tree, (codice .NET che costruisce) una struttura dati che rappresenta l’espressione, che il provider trasformerà in una qualche forma più furba per l’esecuzione (per esempio, una query SQL per un DB relazionale)
  • 27. Riprendiamo la versione “dietetica” var q = /* ... */ .Where(user => user.firstname == "Giovanni") .Select(user => user); In base al tipo della sorgente: public static IEnumerable<T> Where<T>( this IEnumerable<T> source, Func<T, bool> predicate) public static IQueryable<T> Where<T>( this IQueryable<T> source, Expression<Func<T, bool>> predicate)
  • 28. Ma allora, cosa devo usare? IEnumerable<T> IQueryable<T> Dipende, comunque un IEnumerable si converte facilmente con asQueryable Non è (sempre) un cast: int[] ints = { 1, 2, 3 }; IQueryable<int> iq = ints.AsQueryable();
  • 29. Limiti dell’approccio • Alcune espressioni possibili solo con LINQ to Objects, per esempio in LINQ to SQL: var q = from user in context.Users where user.MyMethod()>0 /* boom */ select user.MyMethod() /* ok */ ; – Comunque, molti (tutti?) metodi standard di numeri/stringhe/date vengono tradotti • Mi sembra sconsigliabile, ma limitandosi a LINQ to Objects è possibile modificare gli oggetti visitati
  • 31. ADO Entities Framework • E’ un ORM, al di là di quello che sostiene M$ • Permette di lavorare a livello di Modello E/R (ereditarietà, relazioni molti-a-molti, ...) • Si può interrogare via: – Entities SQL (SQL), per esempio: SELECT VALUE c FROM E.Contacts AS c WHERE c.FirstName='Pippo' – LINQ to Entities La sintassi è quella che vi aspettate
  • 32. Mapping • Descritto da tre file XML – Ma VS li nasconde abbastanza Modello Store Concettuale Mapping Schema (E/R) .MSL Mapping .SSDL .CSDL Specification Language Store Schema Definition Conceptual Schema Language Definition Language (tipicamente) DB Oggetti Relazionale
  • 33. Esempio: Entities vs DB Schema
  • 34. EntityContext Dai file XML otteniamo: • Le classi (parziali) corrispondenti ai tipi entità • Una classe QualcosaEntityContext (che estende ObjectContext) che ci permette di dialogare con il modello, tramite: – proprietà che corrispondono agli insiemi entità – metodi AddTo Il contesto materializza gli oggetti e traccia i cambiamenti, salvati con SaveChanges
  • 35. Esempio di inserimento dati using (var context = new JUGEntities()) { User u = new User() { username = "Gio", firstname="g", lastname="l" }; Role r = new Role() { rolename = "Admin" }; u.Roles.Add(r); Document d = new ToDo() { Author = u, title = "demo", what="boh" }; context.AddToDocuments(d); context.SaveChanges(); // tutti gli oggetti vengono salvati e // l'ordine delle insert e` automatico }
  • 36. Esempio di interrogazione using (var context = new JUGEntities()) { var q = from d in context.Documents.Include("Author.Roles") where d.Author.username=="Gio" select d; var aDoc = q.First(); //aDoc.AuthorReference.Load(); User author = aDoc.Author; Console.WriteLine("Author: {0}nRoles:", author.firstname); //author.Roles.Load(); foreach (Role r in author.Roles) Console.WriteLine("t{0}", r.rolename); }
  • 37. Esempio di modifica/cancellazione using (var context = new JUGEntities()) { var todos = (from d in context.Documents.OfType<ToDo>() select d).ToArray(); context.DeleteObject(todos[0]); todos[1].what = "blabla"; context.SaveChanges(); }
  • 38. LINQ to SQL vs LINQ to Entities Visto che, alla fin fine, si parla di DB relazionali, un confronto è inevitabile. Alcune domande abbastanza ovvie sono: • LINQ to SQL è un ORM? • Quanto si assomigliano? • Posso passare dall’uno all’altro con facilità?
  • 39. LINQ to... SQL Entities E’ un ORM No Sì Cosa si “vede”? Delle tabelle, relazioni 1-n Entità e Relazioni (anche n-m) Ereditarietà No (sì ma...) Sì Transazioni No (ma basta wrappare in Si (su DB singolo, se non basta: ScopeTransaction) ScopeTransaction) Query SQL generate Ragionevoli A volte ragionevoli Da modello a DB e No (ma avrebbe senso?) Solo da VS 2010, purtroppo viceversa? Sincronizzazione No (mi sembra, VS2010?), Sì schema DB? non grave: classi parziali Editor Visuale Sì Sì al 90% (speriamo in VS 2010...) Lazy/eager loading Per context/implicito Per query/esplicito Locking ottimistico Di default su tutto Sì, ma di default su nulla Single/SingleOrDefault Sì No! (Eccezione a runtime)
  • 40. Conclusioni • Oggi: LINQ to – Objects: molto comodo – XML: esiste, non l’ho mai usato – SQL: ok, ma alle “ORMeggia”  a sproposito – Entities: interessante, probabilmente immaturo • Domani? – LINQ in Java? – LINQ to (N)Hibernate: abbastanza non-m$ per essere apprezzato da tutti? – PLINQ, un .AsParallel() rende la query parallela!