Аудит nhibernate с обновлениями - PullRequest
5 голосов
/ 02 июля 2010

Следующий код работает при вставке, но при обновлении modifier никогда не устанавливается, есть идеи, почему?

Код для предварительного обновления выполняется и правильно устанавливает значения состояния и сущности на желаемое значение. Однако при просмотре сгенерированного sql nhibernate не включает поле в запросе на обновление.

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

}

1 Ответ

3 голосов
/ 30 июля 2010

Редактировать 1: Этот ответ был улучшен
Редактировать 2: Похоже, что реальная причина проблемы: dynamic-update установлен в значение true, как найдено здесь однако этоРешение все еще работает для меня.

Изменения сохраняются при их обновлении в функции OnFlushDirty, которая вызывается ранее.

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;
}
...