I\'m trying to implement simple auditing on my entities. Auditable entities implement the ITimestampable
interface which defines DateAdded
and Da
The answer would be hidden/revealed in this cites from Ayende's article
...Here comes the subtlety, however. We cannot just update the entity state. The reason for that is quite simple, the entity state was extracted from the entity and place in the entity state, any change that we make to the entity state would not be reflected in the entity itself. That may cause the database row and the entity instance to go out of sync, and make cause a whole bunch of really nasty problems that you wouldn’t know where to begin debugging.
You have to update both the entity and the entity state in these two event listeners (this is not necessarily the case in other listeners, by the way). Here is a simple example of using these event listeners:
This is the code showing how to, from the same article:
public class AuditEventListener : IPreUpdateEventListener, IPreInsertEventListener
{
public bool OnPreUpdate(PreUpdateEvent @event)
{
var audit = @event.Entity as IHaveAuditInformation;
if (audit == null)
return false;
var time = DateTime.Now;
var name = WindowsIdentity.GetCurrent().Name;
Set(@event.Persister, @event.State, "UpdatedAt", time);
Set(@event.Persister, @event.State, "UpdatedBy", name);
audit.UpdatedAt = time;
audit.UpdatedBy = name;
return false;
}
public bool OnPreInsert(PreInsertEvent @event)
{
var audit = @event.Entity as IHaveAuditInformation;
if (audit == null)
return false;
var time = DateTime.Now;
var name = WindowsIdentity.GetCurrent().Name;
Set(@event.Persister, @event.State, "CreatedAt", time);
Set(@event.Persister, @event.State, "UpdatedAt", time);
Set(@event.Persister, @event.State, "CreatedBy", name);
Set(@event.Persister, @event.State, "UpdatedBy", name);
audit.CreatedAt = time;
audit.CreatedBy = name;
audit.UpdatedAt = time;
audit.UpdatedBy = name;
return false;
}
And here is the magical Set()
private void Set(IEntityPersister persister, object[] state
, string propertyName, object value)
{
var index = Array.IndexOf(persister.PropertyNames, propertyName);
if (index == -1)
return;
state[index] = value;
}