Entity Framework 4 vs NHibernate 3
Upcoming SlideShare
Loading in...5
×
 

Entity Framework 4 vs NHibernate 3

on

  • 664 views

EF Code First e NH, due O/RM a confronto - Un overview su due diverse tecnologie di accesso ai dati

EF Code First e NH, due O/RM a confronto - Un overview su due diverse tecnologie di accesso ai dati

Statistics

Views

Total Views
664
Views on SlideShare
664
Embed Views
0

Actions

Likes
0
Downloads
4
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Entity Framework 4 vs NHibernate 3 Entity Framework 4 vs NHibernate 3 Presentation Transcript

  • PIETRO LIBRO http://efcfvsnh3.codeplex.co MARTINO BORDIN m EF CODE FIRST E NH, DUE O/RM A CONFRONTO Un overview su due diverse tecnologie di accesso ai dati
  • Agenda Mapping, Configuration e creazione del DB Query API CUD Validazione
  • Entity Framework
  • Configuration e Mapping Strategie di utilizzo di Entity Framework  Database First  Model First  Code First Overview sulla versione CTP5 di EF. Solo per Code First ? NO!CTP contiene una versione di preview (nondefinitiva!) delle nuove API che permettono unamaggiore produttività con EF: DbContext
  • DdContext (1) CustomClass: DbContext {...}  ObjectContext Wrapper (vedremo come ricavare l’ObjectContext corrente)  Dal costruttore dipende:  Connessione al Database  Code First Database First Model First  Opzioni avanzate
  • DbContext (2) Code First  Connection by convention  Connection by convention + database name  By connection string  DatabaseModel First, questioni di provider   E altro ancora ...
  • Inizializzazione del db Possibili strategie: Cancella e crea (utile in fase di test): DbDatabase.SetInitializer<Db>(new DropCreateDatabaseAlways<Db>()); Crea se non esiste: DbDatabase.SetInitializer<Db>(new CreateDatabaseIfNotExists<Db>()); Cancella e crea se il modello cambia (!!!): DbDatabase.SetInitializer<Db>(new DropCreateDatabaseIfModelChanges<Db>()); Custom: DbDatabase.SetInitializer<Db>(new DbCustomInitializerStrategy<Db>()); DEMO
  • Mapping (1) Code First Mapping  by Convention (Strategia più semplice)  Overriding conventions  Attributi  Max Length  Column Name  Table Name  ...  Fluent API
  • Mapping (2) Fluent API  Stesse funzioni di mapping degli attributi  Scenari di mapping più complessi (non possibili con attributi)  EntitySplitting (1 Entity N Table)  Configurazione di gerarchie di ereditarietà:  Table per class  Table per class hierarchy  Table per concrete class  Table Splitting (1 Table N Entity)  Override OnModelCreating DEMO
  • Query Caricamento dati, novità:  Find  DbContext.Developers.Find(1)  Include (Tipizzato)  from dev in db.Developers.Include (s=>s.Skills ) where dev.Surname =="Libro"  Load (Carica i dati in memoria senza restituirli)  DbContext.Developers.Load()  AsNoTracking (migliori performance)  DbContext.Developers.AsNoTracking ()  LINQ  (from d in db.Developers select d).FirstOrDefault();  SqlQuery  DbContext.Developers.SqlQuery(query, new object[] { }); //Tracking.  DbContext.Database.SqlQuery<Developer>(); //No
  • Validazione (1) Perché ‘Validare ?’  Dati corretti  Risparmiare trip sul server ( ad esempio - transazioni SQL Azure) In EF  Abilitata per default  Utilizza attributi (DataAnnotations.ValidationAttribute), eventualmente Custom  Validazione automatica dei Complex Type  Supporta l’interfaccia IValidatableObject  Attributi su Navigation Properties e Collection
  • Validazione (2) Perché non usare ?  System.ComponentModel.DataAnnotations.Valida tor In EF, validazione eseguita:  Durante il tentativo di persistenza dei dati  On-demand per singola entità  On-demand per singola proprietà Se la validazione non è effettuata con successo:  DbEntityValidationException (EntityValidationErrors)  DbEntityValidationResult (ValidationErrors)
  • Proprietà (1) Due valori per ogni proprietà:  Current Value (get/set)  entity.Name  Context.Entry(entity).Property(n=>n.name).CurrentValu e  Original Value (get/set)  Context.Entry(entity).Property(n=>name).OriginalValue Lo stesso discorso vale per le proprietà non mappate
  • Proprietà (2) Verificare proprietà modificate:  Context.Entry(entity).Property(n=>n.name).IsModif ied (GetSet)  Forza Update durante il SaveChanges() anche se Original Value e Current Value coincidono Leggere Current, Original e Database Values:  Context.Entry(entity).CurrentValues()  Context.Entry(entity).OriginalValues()  Context.Entry(entity).GetDatabaseValues()
  • Proprietà (3) Original e Current Values da un altro oggetto:  Consideriamo il nostro DTO Developer:  new employeeDTO {Name=‘Pippo’ , Surname=‘Franco’};  Il DTO viene utilizzato da Service Layer per la comunicazione tra strati  Valorizzare la entity da modificare  Context.Entry(entity).CurrentValues.SetValues(employ eeDTO)
  • Concorrenza Concorrenza (ottimistica):  Specifichiamo le proprietà interessate  Attributo [ConcurrencyCheck]  Due possibili patterns:  Store Wins  Utilizziamo il metodo Reload() per sovrascrivere i dati dell’entity con quelli presenti nel database  Client Wins  Sostituiamo i valori originali dell’entity con quelli del database GetDatabaseValues() (eliminazione delle incogruenze) DEMO
  • NHibernate
  • Agenda Mapping, Configuration e creazione del DB Query API CUD, Session & Transaction Validazione
  • Mapping XML FluentNH ConfORM
  • Mapping con XML [NomeTabella].hbm.xml come «Embedded Resource» XSD per validare l’xml prodotto e per l’intellisense di VS
  • Mapping con FluentNH Classi derivanti da (Sub)ClassMap<Entity> Si invocano metodi quali:  Id  Map  HasMany  HasManyToMany  Component DEMO
  • Mapping con ConfORM Creazione di mapping convention-based. ObjectRelationalMapper e Mapper per ottenere un HbmMapping
  • Configuration app|web.config o hibernate.cfg.xml Codice FluentNH ConfORM
  • Configurazione con app|web.config ohibernate.cfg.xml Sezione hibernate-configuration in app|web.config o File hibernate.cfg.xml Metodo Configuration().Configure()
  • Configurazione via codice Configuration mediante fluent interface:new Configuration() .DatabaseIntegration(db => { db.Dialect<MsSql2008Dialect>(); db.ConnectionStringName = «myDB»; }) .AddAssembly(«MappingAssembly»);
  • Configurazione con FluentNH Configuration mediante l’oggetto Fluently:Fluently .Configure() .Database(MsSqlConfiguraiton.MsSQL2008 .ConnectionString(c => c.FromConnectionStringWithKey(«myDB»)) .Mappings(m => m.FluentMappings.AddFromAssembly(..)) .BuildConfiguration(); DEMO
  • Configurazione con ConfORM Si crea la Configuration via codice o FluentNH, e si chiama il metodo config.AddDeserializedMapping(HbmMapping )
  • Creazione del DB Schema Export Setting nella configurazione
  • Creazione del DB con SchemaExport Visulizzazione script sulla console Scrittura script su file Esecuzione new SchemaExport(config) DEMO
  • Creazione del DB con setting nellaconfigurazione hbm2ddl.auto: update, create, create-drop, validate. Con FluentNH: ExposeConfiguration(cfg => cfg .SetProperty("hbm2ddl.auto", " create-drop "));
  • Query API HQL Criteria QueryOver Linq to Nhibernate SQL
  • Query con HQL Sintassi simile a SQL String-based Hqladdin.codeplex.com per Intellisensesession .CreateQuery("select a from Developer a inner join a.Skills c where c.Description = :skillDescription") .SetString("skillDescription", "LINQ") .List<Developer>();
  • Query con Criteria Permette di costruire la Query dinamiche I campi sono espressi mediante stringhesession .CreateCriteria<Developer>() .CreateCriteria("Skills", NHibernate.SqlCommand.JoinType.InnerJoin) .Add(Restrictions.Eq("Description", "LINQ")) .List<Developer>();
  • Query con QueryOver Basata su Criteria, ma è strong-type e «fluent» Introdotta con NH3session .QueryOver<Developer>() .Inner .JoinQueryOver<Skill>(d => d.Skills) .Where(s => s.Description == "LINQ") .List();
  • Query con Linq to NHibernate Permette di sfruttare Linq per effettuare query OOsession .Query<Developer>() .Where(d => d.Skills.Any(s => s.Description == "LINQ")) .ToList();
  • Query con SQL Query SQL scritta su un file hbm.xml embedded.session .CreateSQLQuery(«select count(*) fromcompetenza») .UniqueResult() DEMO
  • Session e Transaction Unit of Work  Mantiene la lista di oggetti coinvolti in una business transaction(*)  Coordina la persistenza delle modifiche  Gestisce la risoluzione della concorrenza.(*)Change tracking
  • Creazione Session SessionFactory.OpenSession(); La creazione della SessionFactory è «onerosa» La creazione della Session è veloce
  • Session API Load/Get per ottenere un oggetto data la sua chiave Save/Update/SaveOrUpdate marca un oggetto come da aggiungere/aggiornare(non lo salva sul database) Delete marca un oggetto come da eliminare Evict sgancia un oggetto dalla sessione Merge (ri)aggancia un oggetto detached alla sessione, in maniera da poterlo persistere correttamente. Refresh (ri)carica un oggetto persistente dal
  • Transaction Session TransactionScope
  • Transaction con Session Si crea una Transaction con session.BeginTransaction Si può eseguire il Commit o il Rollbackvar transaction = session.BeginTransaction();try{ session.Save(developer); transaction.Commit();}catch (Exception){ transaction.Rollback();}
  • Transaction con TransactionScope Permette di creare transazioni distribuite su più sistemi NON sostituisce la transazione di NH using (var scope = new TransactionScope()) { using (var session = sessionFactory.OpenSession()) using (var transaction = session.BeginTransaction()) { // do what you need to do.. session.Save(developer); transaction.Commit(); } scope.Complete(); }
  • Concorrenza Concorrenza (ottimistica):  Version  TimeStamp  Dirty-Checkin DEMO
  • Validazione conNhibernate.Validator Attributi, file nhv.xml, fluent new ValidatorEngine() .GetInvalidValues(customer) Ha 2 event listener per PreInsertEvent e PreUpdateEvent InvalidStateException con un array di InvalidValue
  • CONCLUSIONI
  • Riferimenti Pietro Libro  http://blogs.ugidotnet.org/PietroLibroBlog Martino Bordin  http://blogs.ugidotnet.org/martinobordin Entity Framework – ADO.NET Team Blog  http://blogs.msdn.com/b/adonet NHIbernate  http://nhforge.org/Default.aspx