Entity Framework ed NHibernate a confronto

3 pagine in totale: <<Indietro 1 [2] 3 Avanti >>

NHibernate e Entity Framework all'opera: persistenza delle entità di dominio

Entrambi gli O/RM si presentano all'utilizzatore con un'architettura piuttosto simile: il nucleo centrale è rappresentato da un contesto di persistenza (ObjectContext in ADO.NET Entity Framework, Session nel caso di NHibernate) che implementa una serie di pattern molto comuni per questo tipo di framework. Il contesto di persistenza, infatti, è una Unit Of Work a cui è possibile agganciare le entità di dominio, facendo sì che ne vengano monitorate eventuali modifiche in modo da produrre poi le query di INSERT/UPDATE/DELETE in fase di salvataggio. La principale differenza tra i due riguarda una diversa filosofia di funzionamento del contesto, che porta ADO.NET Entity Framework a richiedere un maggiore intervento da parte dello sviluppatore, con il vantaggio però di consentire più controllo sulle operazioni effettuate verso il database. Un esempio tipico è costituito dalla gestione delle relazioni di associazione tra le entità (es. Fattura e Cliente), che per default vengono risolte e caricate solo dopo l'invocazione del metodo Load():

using (SampleContext context = new SampleContext()) 
{ 
  Fattura fattura = (Fattura) context 
    .GetObjectByKey( 
      new EntityKey("SampleContext.Fatture", "Id", fatturaId)); 
 
  // qui fattura.Cliente è null 
  Debug.Assert(fattura.Cliente == null); 
 
  fattura.ClienteReference.Load(); 
 
  // qui è presente l'istanza di cliente 
  Debug.Assert(fattura.Cliente != null); 
}

Stesso dicasi per la fase di salvataggio: il compito di decidere quando e se procedere con la persistenza delle modifiche è delegato allo sviluppatore e si concretizza solo alla chiamata del metodo SaveChanges().

NHibernate invece ha un approccio diverso, in cui la Session assume i connotati di un vero e proprio gestore di sincronizzazione tra gli oggetti in memory e le relative righe nelle tabelle e ha il potere, in determinate situazioni, di interagire con il database in maniera del tutto autonoma e trasparente. Lo snippet di codice precedente, ad esempio, diviene un qualcosa di questo tipo

using (ISession session = SessionHelper.OpenSession()) 
{ 
  Fattura fattura = session.Get<Fattura>(fatturaId); 
 
  // qui fattura.Cliente non è null, c'è un proxy 
  // non ancora inizializzato 
  Debug.Assert(fattura.Cliente != null); 
 
  // questo statement scatena in maniera trasparente 
  // una SELECT per recuperare i dati del cliente 
  Console.WriteLine(fattura.Cliente.RagioneSociale); 
}

grazie alla funzionalità di Lazy Loading (che sarà inclusa anche in ADO.NET Entity Framework 4.0): se l'oggetto Cliente non è inizializzato, semplicemente accedendo ad uno qualsiasi dei suoi membri viene scatenata la query di SELECT necessaria per popolarne l'istanza.

Addirittura, in alcune situazioni, il framework può decidere in maniera autonoma di persistere delle modifiche su database, come accade nell'esempio seguente, in cui l'engine si accorge che la query eseguita potrebbe essere influenzata dal nuovo valore della proprietà SomeBooleanProperty e pertanto esegue preventivamente la relativa UPDATE.

using (ISession session = SessionHelper.OpenSession()) 
  using (ITransaction tx = session.BeginTransaction()) 
  { 
    Entity entity = session.Get<Entity>(entityId); 
    // modifico una proprietà di questa entity 
    entity.SomeBooleanProperty = false; 
   
    IQuery query = session.CreateQuery( 
      "select count(*) from Entity e where e.SomeBooleanProperty = true"); 
   
    // il risultato della query dipende anche dalla entity 
    // modificata. Prima di eseguirla NHibernate esegue una 
    // UPDATE e salva le modifiche. 
    long res = query.UniqueResult<long>(); 
   
    Console.WriteLine(res); 
  }

Nonostante sembrino simili di primo acchitto, insomma, Session e ObjectContext is comportano in maniera molto diversa. Non è facile decidere quale dei due approcci sia il migliore, e probabilmente non ve n'è uno a priori; in ADO.NET Entity Framework è compito dello sviluppatore stare attento alla consistenza degli statement che coinvolgono fetch e salvataggi di dati, mentre NHibernate si preoccupa autonomamente di assicurarla; un comportamento di questo tipo, però, richiede un'ottima padronanza del framework, altrimenti si rischiano side-effect imprevisti che minano performance e addirittura possono avere un'impatto negativo sul corretto funzionamento dell'applicativo.

3 pagine in totale: <<Indietro 1 [2] 3 Avanti >>

Contenuti dell'articolo

Commenti

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.



Segnala su: Facebook MSDN Social Twitter Segnalo Wikio Diggita Technorati Stumbleupon Google Yahoo FriendFeed Delicious Furl

TUTORIALS
TOP TEN ARTICOLI
ARTICOLI VIA E-EMAIL

Iscriviti alla nostra newsletter nuoviarticoli per ricevere via e-mail le notifiche!

MEDIA
IN EVIDENZA
MISC