2009-03-09 11 views
9

Sto rivisitando e re-implementando il codice che mi ha spinto a chiedere this question sul controllo dei dati in NHibernate. Tuttavia questa volta, io voglio andare con s suggestionSean Carpenter' e attuare l'ISaveOrUpdateEventListener (nuova in NHibernate 2.x)Controllo dei dati in NHibernate usando gli eventi

voglio aggiungere una riga in un database per ogni modifica a ogni proprietà con il valore vecchio e il nuovo quindi più avanti nell'interfaccia utente posso dire cose come "Utente Bob ha cambiato proprietà di Wibble da A a B il 9 marzo 2009 alle 21:04"

Qual è il modo migliore per confrontare lo stato dell'oggetto per capire quale di le proprietà dell'oggetto sono cambiate?

si può ottenere lo stato caricato dell'oggetto dal seguente:

public void OnSaveOrUpdate(SaveOrUpdateEvent saveOrUpdateEvent) 
    { 
     object[] foo = saveOrUpdateEvent.Entry.LoadedState; 
    } 

E suppongo che potrei usare riflessione per capire quali proprietà sono cambiati, ma ho scavato in giro e ci doesn' t sembra essere un insieme di proprietà corrispondenti da confrontare. Avrei pensato che ci sarebbe un metodo GetChangedProperties() o qualcosa del genere.

Potrei sempre ottenere il vecchio oggetto dal database così com'è e confrontarlo, ma questo è ancora un altro database colpito e sembrerebbe pesante in questo scenario.

Qual è la direzione migliore da prendere con questo?

P.S. Nel caso in cui faccia qualche differenza, questo è un progetto di architettura ASP.NET-MVC/S # arp.

risposta

6

Non saprei come ottenere ciò che desideri con l'interfaccia ISaveOrUpdateListener - potresti comunque approfittare del fatto che entrambe le interfacce IPreUpdateEventListener e IPreInsertEventListener forniscono quello che ti serve ... ad es. fare qualcosa del genere:

public bool OnPreUpdate(PreUpdateEvent evt) 
{ 
    string[] names = evt.Persister.PropertyNames; 
    for(int index = 0; index < names.Length; index++) 
    { 
     // compare evt.State[index] to evt.OldState[index] and get 
     // the name of the changed property from 'names' 
     // (...) 
    } 
} 

e fare la stessa cosa per preinserire.

+0

questo ha funzionato per me. Grazie mookid. –

+0

Grazie per "e ottenere il nome della proprietà modificata da" nomi "". Ero in rete da 15 minuti alla ricerca di un modo affidabile per abbinare l'oggetto ai valori. – SamuelKDavis

0

È possibile implementare un modello di Memento per serializzare lo stato dal carico iniziale, tramite ILoadEventListener. Ovviamente non vuoi memorizzare collezioni/relazioni o duplicare l'intero grafico dell'oggetto. Puoi quindi estrarlo e confrontarlo nel tuo ISaveOrUpdateEventListener.

11

si potrebbe anche utilizzare il metodo FindDirty sul persister di lasciare che NHibernate fare i confronti per voi:

var dirtyFieldIndexes = @event.Persister.FindDirty(@event.State, @event.OldState, @event.Entity, @event.Session); 

foreach (var dirtyFieldIndex in dirtyFieldIndexes) 
{ 
    var oldValue = @event.OldState[dirtyFieldIndex]; 
    var newValue = @event.State[dirtyFieldIndex]; 

    // Log values to new "AuditLog" object and save appropriately. 
} 
+0

tutti i tipi di fantastico! –

Problemi correlati