2010-07-02 9 views
5

Der folgende Code funktioniert auf Einfügen, aber auf Update modifier wird nie festgelegt, irgendwelche Ideen warum?Nhibernate Auditing mit Ereignissen auf Update

Der Code für die Voraktualisierung wird ausgeführt und setzt die Status- und Entitätswerte korrekt auf den gewünschten Wert. Wenn jedoch das generierte sql nhibernate angezeigt wird, enthält das Feld nicht in der Aktualisierungsabfrage.

/// <summary> Updates auditable objects </summary> 
public class AuditEventListener : IPreInsertEventListener, IPreUpdateEventListener 
{ 
    private ISecurityManager securityManager; 

    public bool OnPreInsert(PreInsertEvent args) 
    { 
     var auditable = args.Entity as IAuditable; 
     if (auditable != null) { 

      Set(x => auditable.Creator, args.Persister, auditable, args.State, SecurityManager.Identity); 
      Set(x => auditable.DateAdded, args.Persister, auditable, args.State, Clock.Now); 
     } 
     return false; 
    } 

    public bool OnPreUpdate(PreUpdateEvent args) 
    { 
     var auditable = args.Entity as IAuditable; 
     if (auditable != null) { 

      Set(x => auditable.Modifier, args.Persister, auditable, args.State, SecurityManager.Identity); 
      //Set(x => auditable.DateModified, args.Persister, auditable, args.State, Clock.Now); 
     } 
     return false; 
    } 


    /// <summary> Type safe method to update sate and entity </summary> 
    private void Set<T, U>(Expression<Func<U, T>> expression, IEntityPersister persister, U instance, object[] state, T value) 
    { 
     var member = expression.Body as MemberExpression; 
     if (member != null) { 

      var index = Array.IndexOf(persister.PropertyNames, member.Member.Name); 
      if (index == -1) { 
       return; 
      } 
      state[index] = value; 

      var property = (member.Member as PropertyInfo); 
      if (property != null) { 
       property.SetValue(instance, value, null); 
      } 
     } 
    } 

    ISecurityManager SecurityManager 
    { 
     get { /* From IoC */ } 
    } 

} 
+0

Dieser Code sieht gut aus, obwohl die Methode Set ungewöhnlich ist. Wenn Sie einen Haltepunkt auf OnPreUpdate setzen, wird er aufgerufen, wenn Sie ein aktualisiertes Objekt beibehalten? –

+0

Ja es ist, ich denke, das Problem hat etwas damit zu tun, dass die Eigenschaft von Nhibernate nicht als schmutzig angesehen wird. –

Antwort

3

Edit 1: Diese Antwort wurde verbessert
Edit 2: Es scheint, die die wirkliche cuase des Problems ist Dynamic Update Satz auf true als found here aber diese Lösung immer noch für mich funktioniert.

Die Änderungen werden gespeichert, wenn Sie sie in der zuvor aufgerufenen OnFlushDirty-Funktion aktualisieren.

public override bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, NHibernate.Type.IType[] types) 
{ 
    bool result = false; 

    if (entity is IAuditable) { 
     var auditable = (IAuditable)entity; 

     Set(x => auditable.Modifier, propertyNames, auditable, currentState, SecurityManager.Identity); 
     //Set(x => auditable.DateModified, args.Persister, auditable, args.State, TwentyClock.Now); 

     result = true; 
    } 

    return result; 
} 
+0

Ihre verknüpfte "Antwort" verlinkt nur auf die gleiche Seite ....... –

+0

@Max Schilling Sorry, ist diese Antwort besser? –