2011-08-17 90 views
1

我的目标是记录对数据库所做的所有更改(INSERT,UPDATE,DELETE)。此刻,我使用NHibernate的事件监听器API的事件参数的“状态”属性。从post *事件获取数据库值

不幸的是,如果已更改的属性本身是另一个实体或者使用了用户类型,则这种方法无法正常工作。在这些情况下,我想记录实体的Id/db列的值等。

但是我没有在事件args(IEntityPersister,ISession等)中找到任何包含原始值的数据数据库列。这实际上可能吗?

下面是一个示例,其中处理了INSERT操作。 result.DatabaseValues包含已更改的数据。

private DatabaseOperation CreateInsertOperation(PostInsertEvent @event, LoggedClassConfiguration entityLoggingConfiguration) 
    { 
    string tableName = @event.Persister.QuerySpaces.First(); 
    DatabaseOperation result = ... 

    object[] newState = @event.State; 
    for (int i = 0; i < newState.Length; i++) 
    { 
     object newValue = newState[i]; 

     PropertyColumnMapping map = entityLoggingConfiguration.GetMapping(@event.Persister.PropertyNames.ElementAt(i)); 
     if (map == null) 
     { 
      continue; 
     } 

     result.DatabaseValues.Add(new DatabaseValue 
     { 
      NewValue = newValue, 
      FieldName = map.DatabaseColumnName 
     }); 
    } 

    return result; 
    } 

回答

1

我实现了一个记录是这样的:

var persister = anEvent.Persister; 
for (int i = 0; i < persister.PropertyNames.Length; i++) 
{ 
    var propertyType = persister.PropertyTypes[i]; 
    if (!propertyType.IsCollectionType) 
    { 
     var insertEvent = anEvent as PostInsertEvent; 
     if (insertEvent != null) 
     { 
      var logEntry = (AuditLog) baseLog.Clone(); 
      logEntry.PropertyName = persister.PropertyNames[i]; 
      logEntry.PropertyNewValue = this.GetStateValue(insertEvent.State[i]); 
      logger.DebugFormat("Feld hinzugefuegt: '{0}' => '{1}'", logEntry.PropertyName, logEntry.PropertyNewValue); 
      Session.Save(logEntry); 
     } 
    } 
} 

有了这样你每次插入到数据库propter。您遇到的唯一问题是集合类型和参考。

如果我今天实施了AuditLogging,那么我会将所有信息保存到XML中,并保存到CLOB数据库字段中。

+0

感谢您解决此问题的解决方案。但是你没有得到实际的数据库值,是吗?如果使用用户类型会怎么样?而且,这是如何处理外键的一个人的地址ID? – Antineutrino 2011-08-19 05:49:15