使用NHibernate事件监听器进行审计以忽略某些属性更改

时间:2010-10-15 13:00:30

标签: c# nhibernate event-listener

我已经连接登录我的应用程序,使用事件监听器自动记录对某些实体的更改。这很好用但是对于我正在记录的实体的一些属性,如果只对该属性进行了更改,我不希望插入日志。这些属性使用IgnoreLoggingAttribute属性进行修饰。以下是我到目前为止的情况:

public void OnPostUpdate(PostUpdateEvent @event)
{
    var session = @event.Session.GetSession(NHibernate.EntityMode.Poco);

    if (@event.Entity is User)
        session.SaveOrUpdate(new UserLog((User)@event.Entity));
    ...
}

@event公开了2个名为State和OldState的属性。我可以使用它来检查更改但是我无法提取我感兴趣的属性,因为这些只是一个对象数组。我想我可以使用一些反射来获取所有索引(对于具有IgnoreLoggingAttribute的任何属性)并将它们与对象数组中的那些匹配。到目前为止,我想出了:

var properties = typeof(User).GetProperties().Where(p => p.GetCustomAttributes(typeof(IgnoreLoggingAttribute), false).Count() > 0);

现在的问题是它没有给我原始实体的属性索引。我还需要确保它匹配来自@ event.State和@ event.OldState属性的适当索引(它们似乎都忽略了某些属性)。

2 个答案:

答案 0 :(得分:3)

我可以通过在插入日志表之前调用此方法来实现此目的:

private bool IsDirty(PostUpdateEvent @event) {
    // Get all the mapped property names
    var propertyNames = @event.Session.Factory.GetClassMetadata(@event.Entity.GetType()).PropertyNames;

    // Get the property index to ignore
    var propertyIndexesToIgnore = @event.Entity.GetType().GetProperties()
        .Where(p => p.GetCustomAttributes(typeof(IgnoreLoggingAttribute), false).Count() > 0)
        .Select(p => Array.IndexOf(propertyNames, p.Name)).ToArray();

    if (@event.OldState != null && @event.State != null) {
        for (var i = 0; i < @event.OldState.Length; i++) {
            if (!propertyIndexesToIgnore.Contains(i) && !@event.OldState[i].Equals(@event.State[i]))
                return true;
        }
    }

    return false;
}

现在我所要做的就是将IgnoreLoggingAttribute属性应用于我不想记录的任何属性。希望这会有所帮助。

答案 1 :(得分:0)