开发者

Getting database values from post* events

开发者 https://www.devze.com 2023-03-29 05:09 出处:网络
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.

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

精彩评论

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