2010-10-15 52 views
1

我已经将日志记录在我的应用程序中,以便使用事件监听器自动将更改记录到某些实体。这很好,但对于我正在记录的实体的一些属性,如果只对该属性进行更改,我不希望插入日志。这些属性用IgnoreLoggingAttribute属性装饰。这是我到目前为止:审计以忽略NHibernate事件监听器的某些属性更改

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属性的适当索引(这两个属性似乎都忽略了某些属性)。

回答

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) && [email protected][i].Equals(@event.State[i])) 
       return true; 
     } 
    } 

    return false; 
} 

现在我需要做的就是应用IgnoreLoggingAttribute属性的任何属性,我不希望记录。希望这可以帮助。