Entity Framework 4.0 vs NHibernate

4,651 views

Published on

Come possiamo persistere i dati del dominio applicativo in modo trasparente rispetto alla logica di business utilizzando un ORM

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,651
On SlideShare
0
From Embeds
0
Number of Embeds
42
Actions
Shares
0
Downloads
0
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Entity Framework 4.0 vs NHibernate

  1. 1. EntityFramework 4.0vsNHibernate<br />Speaker:Manuel Scapolan<br />info@manuelscapolan.itwww.manuelscapolan.it<br />
  2. 2. 2<br />In questa sessione parleremo di …<br />… come possiamo persistere i dati del dominio applicativo in modo trasparente rispetto alla logica di business utilizzando un ORM<br />
  3. 3. 3<br />Siamo nel mondo delle “Enterprise Applications”<br />Forte interazione con l’utente (concorrenza)<br />Gestione e persistenza di grandi quantità di dati<br />Logica di business complessa<br />Necessità di integrazione con altre applicazioni<br />
  4. 4. 4<br />Architettura a layer<br />Presentation Layer<br />Business Layer<br />Persistence Layer<br />
  5. 5. Architettura a layer<br />PresentationLayer<br />Utility<br />Business Layer<br />PersistenceLayer<br />5<br />Database<br />
  6. 6. 6<br />Organizzazione della logica di dominio<br />Transaction script<br />Table Model<br />Domain Model<br />
  7. 7. 7<br />Transaction script, ovvero la classe “Manager”<br />Tende a fare tante, troppe cose<br />In alcuni casi è solo un insieme di metodi statici<br />Problema di duplicazione di codice<br />Presenza di molti “switch-case” o “if – else if”<br />
  8. 8. 8<br />Transaction script: perché SI e perché NO<br />SI: Velocità di realizzazione in progetti piccoli e con un dominio “semplice”<br />NO: Duplicazione di codice e difficoltà a mantenere Single-Responsability e basso accoppiamento in modelli di dominio con complessità crescente<br />
  9. 9. 9<br />Table Model<br />A single istance that handles the business logic for all rows in a database table or viewPoEAA – Martin Fowler<br />Organizza il modello di dominio in tabelle<br />Lavora per record-set<br />Un esempio: i dataset<br />
  10. 10. 10<br />Table Model: perché SI e perché NO<br />SI: Velocità di realizzazione, minore accoppiamento rispetto al transaction script e maggiore facilità di interazione con le altre componenti del sistema (presentation & storage)<br />NO: Impossibilità di raffinare l’organizzazione del dominio utilizzando tecniche di OOP (es. inheritance, strategies, design patterns, …)<br />
  11. 11. 11<br />Domain Model<br />An object model of the domain that incorporates both behavior and dataPoEAA – Martin Fowler<br />Descrive le entità del sistema tramite caratteristiche, comportamenti e ruoli<br />Gli oggetti definiti nel modello non sono solo entità, ma anche classi che collaborano tra loro per risolvere problemi di business <br />
  12. 12. 12<br />Domain Model: perché SI<br />Separation of Concerns<br />Design for Testability<br />Single-Responsability<br />High Cohesion & Low Coupling<br />… what else?<br />
  13. 13. 13<br />The Object-Relational Impedance Mismatch<br />Se vogliamo persistere i dati del dominio in un database relazionale dobbiamo scontrarci con le differenze tra oggetto e relazione<br />Tipi primitivi (es. string e varchar)<br />Identità di dominio <br />Ereditarietà tra entità<br />Granularità<br />Associazioni tra entità e “relationships”<br />Transazioni e conversazioni (business transactions)<br />
  14. 14. 14<br />Domain Model e persistenza dei dati<br />Per mantenere separati logica di business e persistenza dei dati dobbiamo usare gli strumenti giusti!<br />Dominio semplice: Active Record<br />Dominio complesso: Data Mapper<br />Obiettivo: “Persistence Ignorance”<br />
  15. 15. 15<br />Active Record<br />Oggetto che mappa una entità per riga di una tabella del database e contiene la logica di dominio per gestirla<br />Il modello di dominio è una fotografia del database<br />La mappatura è veloce, ma si adatta con difficoltà al crescere della complessità del modello<br />
  16. 16. 16<br />Active Record, un esempio<br />[ActiveRecord] publicclass Blog : ActiveRecordBase<Blog> { privateintid; [PrimaryKey] privateintId { get { returnid; } set { id = value; } } [Property] publicstringName { get; set; } [Property] publicstringAuthor{ get; set; } } <br />// SavenewBlogblog = new Blog();blog.name = “Manuel’s blog”;blog.Author = “Manuel Scapolan”;blog.Save();// Find and UpdateBlogblog= Blog.Find(1);blog.name= “Il blog di Manuel”;blog.Update(); <br />
  17. 17. 17<br />Data Mapper<br />A layer of Mappers that moves data between objects and database while keeping them independent of each other and the mapper itselfPoEAA – Martin Fowler<br />Libera il modello di dominio dalla logica di persistenza e dalla struttura del database!<br />E’ uno strato software tra i layer business e persistence<br />
  18. 18. 18<br />ORM (Object Relational Mapping)<br />Data Mapper che si basa sulla definizione di metadati per rappresentare le relazioni tra modello di dominio e database<br />Una volta mappate le classi sulle tabelle non dobbiamo più preoccuparci dell’accesso ai dati della nostra applicazione!?<br />
  19. 19. 19<br />No ORM no party<br />Dobbiamo scrivere molto codice di plumbing: ripetitivo, poco flessibile e molto error-prone<br />
  20. 20. 20<br />Entity Framework 4.0 vs NHibernate<br />NHIBERNATE<br />
  21. 21. 21<br />NHibernate, alcune informazioni<br />Framework ORM per la piattaforma .NET <br />Porting idiomatico da Hibernate scritto in java<br />Free e open source, distribuito con licenza LGPL<br />Nasce alla fine del 2005 come progetto JBoss<br />Dalla fine del 2006 interamente sviluppato e supportato dalla community <br />
  22. 22. 22<br />Come partire<br />Scaricare NHibernate da SourceForge<br />Nel progetto aggiungere reference e procedere alla configurazione da file hibernate.cfg.xml<br />Definire il mapping delle entità …<br />
  23. 23. 23<br />Il mapping delle entità<br />Il mapping può essere fatto:<br />Decorando con attributi la classe e le sue proprietà<br />Attraverso un file xml<br />Con la nuova libreria FluentNHibernate<br />Con un approccio customizzato<br />
  24. 24. 24<br />Interagire con la base dati<br />Tramite l’interfaccia ISession possiamo avere:<br />esecuzione di operazioni CRUD sulle entità in modo facile e trasparente<br />gestione delle modifiche in una Unit of Work<br />cache di primo livello tramite Identity Map<br />gestione delle transazioni<br />
  25. 25. 25<br />Come leggere i dati dal database …<br />I metodi Get e Load dell’interfaccia ISession ci permettono di prelevare una entità dal db tramite la sua chiave primaria (IdentityField)<br />… e se volessimo di più?!<br />
  26. 26. 26<br />Interrogazioni con “Dynamic Querying”<br />Le query vengono descritte tramite:<br />Hibernate Query Language (HQL):linguaggio SQL-like sugli oggetti del dominio<br />Criteria API:insieme di classi che realizzano il pattern Query Object<br />Il codice SQL viene poi generato a runtime ed eseguito sul db dalla stored sp_executesql<br />
  27. 27. 27<br />Nessuna limitazione rispetto al linguaggio SQL<br />Aggregazioni<br />Ordinamenti<br />Raggruppamenti<br />Subquery<br />selectcatfromCatcat<br />join cat.kittenskitten<br />groupbycat.id, cat.name, cat.other, cat.properties<br />havingavg(kitten.weight) > 100 <br />orderbycount(kitten) asc, sum(kitten.weight) desc<br />
  28. 28. 28<br />Lazy Load<br />Caricare le entità solo quando servono<br />Attenzione a mantenere aperta la sessione altrimenti: LazyInitializationException<br />Possiamo farlo anche noi, ma se lo fa qualcun altro su nostra richiesta è meglio!<br />
  29. 29. 29<br />Persistere le modifiche sul database <br />ISession.Save(entity)<br />oppure<br />ISession.Update(entity)<br />oppure<br />ISession.SaveOrUpdate(entity)<br />e poi<br />ISession.Flush() o ISession.Close()<br />
  30. 30. 30<br />La “Persistence ignorance” ha un prezzo …<br />Performance: si fa tutto via reflection<br />Implicazioni nella definizione delle entità di dominio:<br />No readonly field<br />Obbligatorio il costruttore di default senza parametri<br />Evitare collezioni strongly-typed (sì ai generics)<br />Non impostare valori su Identity Fields<br />Se vogliamo il lazy load metodi e proprietà devono essere definiti virtual<br />
  31. 31. 31<br />Se il vostro DBA sapesse che …<br />Il codice generato in scenari complessi non è proprio così pulito<br />Si possono verificare problemi di performance e carico sul server<br />Potrebbe essere eseguito del codice ‘inaspettato’<br />
  32. 32. 32<br />Come convincere il DBA<br />Fate attenzione al mapping delle entità<br />Modificate le strategie di fetching dal file di mapping<br />Controllate sempre con il profiler il codice SQL generato<br />Testate i mapping delle entità<br />Evitate dove possibile l’utilizzo di associazioni molti a molti<br />
  33. 33. 33<br />Entity Framework 4.0 vs NHibernate<br />ENTITY FRAMEWORK<br />
  34. 34. 34<br />Entity Framework: di cosa stiamo parlando?<br />Framework ORM di casa Microsoft per la persistenza delle entità di dominio<br />
  35. 35. L’accesso ai dati secondo Microsoft<br />35<br />Evoluzionedi ADO.NET<br />ADO.NET<br />2.0 (Classic)<br />Entity<br />Framework<br />LINQ<br />to<br />SQL<br />ADO.NET<br />Data <br />Services<br />Azure<br />Table<br />Services<br />RIA<br />Services<br />
  36. 36. 36<br />ORM by Microsoft<br />LINQ to SQL<br />Entity Framework<br />
  37. 37. 37<br />Entity Framework 1.0 vs NHibernate<br />Ti piace vincere facile?<br />Designer troppo “acerbo”<br />No Model First, ovvero dal database il dominio <br />No POCO, no “Persistence Ignorance”<br />Lazy Loading non supportato<br />SQL generato illeggibile<br />e altro ancora … <br />
  38. 38. 38<br />Entity Framework 4.0<br />Ora è più maturo, ora è pronto per la sfida:<br />Sì a PersistenceIgnorance e POCO<br />Sì Model-First, ovvero partiamo dal modello<br />Sì LazyLoad<br />Designer migliorato<br />Codice SQL generato più pulito<br />
  39. 39. Entity Data Model (EDM)<br />Permette di definire da designer le entità del dominio con attributi e associazioni<br />“Sotto le coperte” ci sono tre schemi concettuali definiti in xml:<br />CSDL (Conceptual Schema DefinitionLanguage)<br />SSDL (Storage Schema DefinitionLanguage)<br />MSL (Mapping Schema Language) <br />39<br />
  40. 40. Il modello di dominio dal database<br />Le classi del modello derivano tutte da EntityObject<br />40<br />
  41. 41. Il modello dal database, sì ma POCO<br />Con il Text TemplateTransformation Toolkit (T4) si può:<br />41<br />
  42. 42. Come usare le nostre classi POCO<br />Il segreto è tutto nell’ObjectContext dove sono definite le classi di dominio gestite dall’EntityFramework<br />Poi dobbiamo rimappare a mano le entità nell’EDM<br />42<br />
  43. 43. Dal modello al database<br />E’ possibile dal modello generare uno script DDL per creare da zero il database<br />43<br />
  44. 44. Interrogare il modello dei dati<br />Entity-SQL (eSQL) : un linguaggio SQL-like più adatto in caso di query dinamiche (no Projections)<br />LINQ-to-Entities: un dialetto di LINQ per l’EntityFramework, permette di avere querystrongly-typed e intellisense sui tipi<br />44<br />
  45. 45. LazyLoad<br />Lavora con classi proxy e quindi:<br />Tutte le proprietà devono essere virtual<br />Bisogna utilizzare ICollection<T> per le collezioni<br />La classe non può essere sealed<br />Deve esserci un costruttore senza parametri<br />La classe non può essere abstract<br />Per avere eagerload devo usare “Include”<br />45<br />
  46. 46. Tracciare le modifiche alle entità<br />L’ObjectContext è una cache di oggetti in memoria che permette di tenere traccia dei cambiamenti di stato dei suoi elementi (attraverso l’ObjectStateManager)<br />Esiste un’API per la gestione delle entità e del loro stato (Attach e Detach, ChangeObjectState, AddObject, …)<br />46<br />
  47. 47. Tracciare le modifiche di un POCO<br />SnapshotbasedChangeTracking, con SaveChanges persisto tutte le modifiche in un colpo solo, con DetectChanges riallineo<br />Notification based Change Tracking with Proxies, ilcontesto è sempreallineato<br />47<br />
  48. 48. In conclusione …<br />Se la logica di business è organizzata in un modello di dominio l’accesso ai dati tramite ORM diventa una scelta quasi obbligata<br />Qualsiasi sia poi l’ORM adottato è fondamentale conoscerne le potenzialità ed i limiti<br />… e se invece la fonte dei nostri problemi fosse il caro e vecchio database relazionale?<br />48<br />
  49. 49. 49<br />Alcuni libri per approfondire l’argomento<br />PoEAA (Patterns Of Enterprise Application Architecture)Martin Fowler – Addison-Wesley<br />Applying Domain Driven Design and PatternsJimmy Nilsson – Addison Wesley<br />NHibernate in ActionPierre Henri Kuaté – Manning<br />Programming Entity Framework Julia Lerman – O'Reilly<br />
  50. 50. 50<br />Entity Framework 4.0 vs NHibernate<br />CONTATTI:<br />Manuel Scapolan<br />mail: info@manuelscapolan.itsito web: www.manuelscapolan.it<br />1nn0va<br />mail: info@1nn0va.netsito web: www.1nn0va.net<br />

×