开发者

Getting database values from post* events

my goal is to log all changes (INSERT, UPDATE, DELETE) made to the database. At the moment I use the "state" properties of the event args from the event listener API of NHibernate.

Unfortunately this doesn't work well if the changed property itself is another entity or if a user type is used. In these cases I would lik开发者_StackOverflowe to log the entity's Id/the value of the db columns etc.

But I did not found any data in the event args (IEntityPersister, ISession, etc.) that contain the original values of the db columns. Is this actually possible?

Here's a sample where an INSERT operation in handled. result.DatabaseValues contains the changed data.

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


I implemented a logger this way:

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

With this Way you get every propter which is inserted into the database. The only problem you have is with collection types and the references.

If I implemented an AuditLogging today, I would persist all Information into XML into a CLOB Database field.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜