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