2009-07-20 1 views
11

Sto usando DDD e NHibernate per mantenere il mio oggetto dominio. Nel mio database ogni tabella correlata a un'entità ha quattro colonne aggiuntive (CreatedBy, UpdatedBy, CreatedDate, UpdatedDate) utilizzate per il tracciamento del controllo. Sto usando il modello di repository che consente di salvare solo le root aggregate. Quando NHibernate tenta di salvare le entità sulla radice aggregata, ottengo un errore SQL DateTime perché le entità non hanno le loro proprietà di controllo impostate. C'è un modo in NHibernate per impostare le proprietà sugli oggetti prima del salvataggio?NHibernate imposta automaticamente le proprietà al salvataggio

Ecco un piccolo esempio. Ho un oggetto Order che è la radice aggregata. Ho anche oggetti OrderNote che sono figli dell'ordine. Quando aggiungo un OrderNote all'Ordine e quindi salvo l'Ordine, viene generata un'eccezione perché CreatedDate/UpdatedDate è impostato su DateTime.MinValue che causerà un overflow SQL DateTime. Poiché queste colonne di controllo fanno parte della persistenza e non sono correlate al dominio del problema, non desidero che la radice di aggregazione degli ordini imposti queste proprietà quando viene aggiunta la nota. Le colonne/proprietà di controllo dovrebbero essere conosciute solo dal framework di persistenza e non dal dominio. Vorrei poter dire a NHibernate di impostare queste proprietà durante il salvataggio o l'aggiornamento. C'è un modo per fare questo?

risposta

11

intercettori possono fare questo:

http://www.nhforge.org/doc/nh/en/index.html#manipulatingdata-interceptors (9,10, link non sempre funziona).

taglia/incolla dal documento:

public class AuditInterceptor : IInterceptor 
{ 
    ... 

    public boolean OnSave(object entity, 
          object id, 
          object[] state, 
          string[] propertyNames, 
          IType[] types) 
    { 
     if (entity is IAuditable) 
     { 
      for (int i=0; i<propertyNames.Length; i++) 
      { 
       if ("CreateTimestamp" == propertyNames[i]) 
       { 
        state[i] = DateTime.Now; 
        return true; 
       } 
      } 
     } 
     return false; 
    } 

} 

OnFlushDirty() potrebbe essere utilizzato per UpdatedDate.

Si desidera che tutte le entità che dispongono di un DataData/AggiornamentoDate implementino un'interfaccia in modo che l'intercettatore possa verificare se deve agire (nell'esempio fornito è IAuditable).


Modifica

Appena notato il capitolo 11: Intercettori ed eventi. Puoi ereditare da EmptyInterceptor che semplifica le cose se hai solo bisogno di sovrascrivere alcuni dei metodi.

Non ho mai usato Eventi.

+0

Grande. Questo è esattamente quello che sto cercando. Sono nuovo di NHibernate e non ero a conoscenza di questa funzionalità. Ho un'interfaccia IAuditable implementata con proprietà protette in modo che il dominio non possa vederle. – awilinsk

1

Si potrebbe anche guardare il sistema di controllo delle versioni di NHibernate, che può aiutarti nel tuo caso;)