I spent some time reading a few posts and articles about audit tracking but still can't figure this out.
What I need is a pretty basic audit system that will give me results such as:
- Customer "John Doe" was deleted by "User"
- Customer "Jane Doe" was created by "Other User"
- Address from "John Doe" was modified by "User"
- Customer "Jane Doe" was removed by "Other User"
I tried to override the SaveChanges event on dbContext but i got stuck with the following problem:
public override int SaveChanges()
{
foreach (DbEntityEntry<IAuditable> entry in ChangeTracker.Entries<IAuditable>())
{
if (entry.State == EntityState.Added)
{
// since the object was not added yet, if I write to log in here and
// for some reason SaveChanges fail, I will end up with a fake log entry
}
else if (entry.State == EntityState.Modified)
{
// same in here
}
}
return base.SaveChanges();
// here the state for all entries have changed to Unchanged or Detached.
// detached is probably the one that was deleted however the “Unchanged”
// could be new or modified records.
}
I know I could use triggers on the database to accomplish this but I'd like to keep it here so I have more control over it, since I'm not an SQL guy and after deploy the application I won't have that much control over the db.
I'm 'sure I'm missing something very simple here. I appreciate any help.
Thanks in advance.
You can always check if there are any audit entries in your context and remove them when your SaveChanges is called. It will solve your first issue - you will always remove previous audit entries prior to creating a new one.
The second problem cannot be solved with DbContext API. DbContext API is simplification of ObjectContext API and this simplification removed methods needed for complex scenarios. One such method is overloaded version of
SaveChangeswith ability to not accept changes (not change states of entities).You can convert
DbContexttoObjectContextthroughIObjectContextAdapter. Even withObjectContextit will not be straight forward: