I'm using the Entity Framework to construct a basic repository to add/delete/update Customer records.
One thing I want is to be able to have Customer row auditing so that I have a second table CustomerAudit that should get an entry added every time you add/update/delete a row. In the old wyrld this would be done with a database trigger on update/on delete/on insert etc. Now, I'm trying to do it by overriding the SaveChanges() method of the DBContext object, leveraging the ChangeTracker object and using that to create an audit record based on the data being saved/updated with the current date time and inserting that alongside the actual row. Code below.
The problem I have is that when you update or delete, this works fine as it writes the most recent record to the audit table which will have either the updated values or the final values before deletion, along with the current timestamp of when this activity occurred.
When you add a record though, it inserts a record in the audit table, but as the actual row hasn't been inserted yet (with identity insert) you dont yet have the CustomerId and so it inserts an audit record with the correct data but with a CustomerId of 0, which is no good for auditing.
Any thoughts on how I can get the auditing working for adding records to?
public class CustomerDbContext : DbContext
{
public CustomerDbContext()
{
Database.SetInitializer(new CreateDatabaseIfNotExists<CustomerDbContext>());
}
public DbSet<Customer> Customers { get; set; }
public DbSet<CustomerAudit> CustomerAudits { get; set; }
public override int SaveChanges()
{
// Get all Added/Deleted/Modified entities (not Unmodified or Detached)
foreach (var ent in ChangeTracker.Entries().Where(p => p.State == System.Data.EntityState.Added || p.State == System.Data.EntityState.Deleted || p.State == System.Data.EntityState.Modified))
{
var auditRecord = GetAuditRecord(ent);
if (auditRecord != null)
CustomerAudits.Add(auditRecord);
}
// Call the original SaveChanges(), which will save both the changes made and the audit records
return base.SaveChanges();
}
private static CustomerAudit GetAuditRecord(DbEntityEntry dbEntry)
{
var changedRecord = dbEntry.Entity as Customer;
return changedRecord == null ? null : new CustomerAudit(changedRecord);
}
}
PKtype frominttoGUID. TheGUIDwill be generated when instantiating aCustomerentity, and you will know in advance what value will have (customer.Id == '4705b72f-1e5b-4d0c-90d9-c235750f8b13')