2010-07-02 8 views
5

El siguiente código funciona en la inserción, pero en la actualización modifier nunca se establece, ¿alguna idea de por qué?auditoría de nhibernate con eventos en la actualización

El código para la preactualización se está ejecutando y establece correctamente los valores de estado y entidad en el valor deseado. Sin embargo, al visualizar el sql nhibernate generado no se incluye el campo en la consulta de actualización.

/// <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

Este código me parece bien, aunque el método Set es inusual. Si coloca un punto de interrupción en OnPreUpdate ¿se llama cuando persiste un objeto actualizado? –

+0

Sí, lo es, creo que el problema tiene algo que ver con que la propiedad no sea considerada sucia por nhibernate. –

Respuesta

3

Edición 1: Esta respuesta ha sido mejorada
Edición 2: Parece que la del cuase real del problema es dinámica de actualización conjunto a cierto como found here Sin embargo esta solución todavía funciona para mí.

Los cambios se guardan cuando los actualiza en la función OnFlushDirty que se llama anteriormente.

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

su "respuesta" vinculada solo enlaces a la misma página ....... –

+0

@ Max Schilling Lo sentimos, esta es la respuesta mejor? –

Cuestiones relacionadas