Immaginate un bella classettina così composta:
(I puristi mi perdoneranno per il non uso delle property ma le ho omesse solo per salvare spazio...e perchè non ho il mio portatile e scrivo da web!!)
Public Class Fattura
Public Numero as Integer
Public Anno as integer
Public Data as Datetime
Public Cliente as Cliente
Public Ordine as Ordine
Public Dettagli as DettaglioFatturaCollection
Public Sub New()
'Inizializza un po tutto :-)
End Sub
End Class
La classe Fattura aggrega una istanza di tipo Cliente e una di tipo Ordine e ha anche una bella custom collection tipizzata per contenere i suoi dettagli.Qualche altro campo per il numero e data di fattura e dal punto di vista del Domain Model sono apposto così.
Non voglio approfondire quale sia la modalità di mapping di un oggetto del genere ma solo parlare di una particolarità di comportamento di NHibernate che è veramente un piccolo gioiellino...
Tramite questa feature chiamata Persistence by Reachability il persistence manager assicura che al momento in cui un oggetto viene persistito, tutti gli oggetti che referenzia (e che hanno una mappatura) saranno persistiti.
E se glielo chiediamo pure...sarà tutto fatto in contesto transazionale.
Che vuol dire?
In soldoni che io faccio qualcosa del genere:
Dim fattura as Fattura = session.Get(GetType(Fattura), numeroFattura) ' con questo da Nhibernate ottengo il caricamento dell'oggetto fattura
fattura.Data = Now
fattura.Ordine.Confermato = true;
fattura.Cliente.RagioneSociale = "La cambio qui perchè sono pazzo"
fattura.Cliente.Responsabile.Nome = "Cambio qui perchè sono ancora più pazzo" 'Responsabile potrebbe essere un ulteriore oggetto Persona aggregato in Cliente
fattura.Dettagli.Add(new nuovoDettaglio)
fattura.Dettagli(3).Descrizione = "Qualcosa"
fattura.Dettagli.RemoveAt(4)
'e via dicendo
e solo con la magica
Dim tx as ITransaction = session.BeginTransaction 'notare che il tipo ITransaction è generico per tutti i DB!!
session.SaveOrUpdate(fattura)
tx.Commit
Tre (ripeto Tre!) sole righe di codice e verranno scatenate le dovute SQL per aggiornare
l'oggetto Cliente (aggregato), l'oggetto Ordine (aggregato), l'oggetto Fattura (aggregatore), e tutta la collezione di dettagli fattura (insert update e delete del caso). Che sia gestito in maniera transazionale o no, siccome Nhibernate è furbo tutte le SQL passeranno in un unico RoundTrip con il DB.(Ho dei sospetti che la session viva di vita propria...inquietante!)
Provate ad attivare SQL Profiler e sniffare cosa passa sul DB.
Questa è la magia della persistenza.
Meditate gente, meditate.
Alla prossima un confronto tra dataset e Domain model....(aaaahhh li ho messi assieme nella stessa frase!!)
Maggiori dettagli?
sempre qui
Scrivere meno codice usando blocchi già pronti? Si può: NHibernate e Enterprise Library!
Ai soci Ugi c'è pure lo sconto!