i'm using EF 4.3.1, I've overridden the SaveChanges() on the context so that I can get a list of the objects and their states and create entries in my audit log table. I need to store the id of the record in the audit log table so i have a reference to it. This is a problem when records are inserted, as I don't have access to the id before it's saved. Is there any way of getting the id at that point?
public override int SaveChanges()
{
ChangeTracker.DetectChanges();
var objectStateManager = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager;
var modifiedAuditableEntities = objectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added).Where(e => (IAuditable)e.Entity != null);
foreach (var entry in modifiedAuditableEntities)
{
var entity = (IAuditable)entry.Entity;
if (entity != null)
{
switch (entry.State)
{
case EntityState.Added:
entity.IsAdded = true;
break;
case EntityState.Deleted:
entity.IsDeleted = true;
break;
case EntityState.Modified:
entity.IsModified = true;
break;
}
this.EntitySet<AuditLogEntry>().Add(this.auditLogService.CreateAuditLogEntryForEntity((IAuditable)entry.Entity));
}
return base.SaveChanges();
}
If your goal is that you want both your save, and your audit log to be created at the same time, you could wrap it in a transaction scope so your method to be atomic.
public override int SaveChanges()
{
ChangeTracker.DetectChanges();
using (var scope = new TransactionScope())
{
var objectStateManager = ((IObjectContextAdapter) this).ObjectContext.ObjectStateManager;
var modifiedAuditableEntities =
objectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added).Where(
e => (IAuditable) e.Entity != null);
var result = base.SaveChanges();
foreach (var entry in modifiedAuditableEntities)
{
var entity = (IAuditable) entry.Entity;
if (entity != null)
{
switch (entry.State)
{
case EntityState.Added:
entity.IsAdded = true;
break;
case EntityState.Deleted:
entity.IsDeleted = true;
break;
case EntityState.Modified:
entity.IsModified = true;
break;
}
this.EntitySet<AuditLogEntry>().Add(
this.auditLogService.CreateAuditLogEntryForEntity((IAuditable) entry.Entity));
}
}
base.SaveChanges();
scope.Complete();
return result;
}
}