2011-08-17 265 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