Difference between SavingChanges event vs SaveChanges override?

c# entity-framework entity-framework-6

Question

I've read multiple posts about how to implement an audit log using entity framework. I currently have the audit logic embedded in the SaveChanges method in the DbContext. Please keep in mind that the code below is an EF4/5 implementation and I'm preparing to update to EF6.

namespace Database {
    public class AuditDetails {
        public string RemoteHost { get; set; }
        public string RevisionUser { get; set; }
        public string RevisionNotes { get; set; }
        public DateTime RevisionDateTime { get; set; }
    }

    public class MyContext : DbContext {
        // ... Unrelated overrides here ... //
        public void SaveChanges(AuditDetails auditDetails) {
            var saveCount = ProcessConcurrency();
            var items = ChangeTracker.Entries<MyEntity>().ToList();
            if (saveCount <= 0 || items == null || !items.Any() || auditDetails == null) return;
            foreach (var item in items.Select(entityEntry => entityEntry.Entity).Where(i => i != null)) {
                // ... create audit log using AuditDetails values ... //
            }
            // ... and call base.SaveChanges() ... //
        }
    }
}

So the questions would be:

  • Is there a benefit to moving this to a SavingChanges event handler? Or possibly split the functionality to use both?
  • Does the AuditDetails information preclude using SavingChanges?
  • I do not have an override for SaveChanges that accepts the Boolean argument for use in transactions. How would adding that change the solution?

In Summary:

  • When would you override/implement SaveChanges and when/why would you prefer to use a SavingChanges event handler?
1
2
1/9/2015 9:38:07 PM

Accepted Answer

I don't think it really matters in most cases. There are three situations I can think of that demand one of both options:

  1. SaveChanges should be overridden completely, so base.SaveChanges should not be called: only an override can do this.

  2. Another class is involved in what happens on saving changes: only the event can do that. (Or maybe I should say: an event would be the obvious pattern to choose).

  3. You want to extend SaveChanges optionally. To my taste it's cleaner to activate the event in the constructor by some parameter than to start an override with if (option), where option must have been stored as a member variable.

In all other cases I'd always use the override. The event requires the ObjectContext to be dug up first (because it's ObjectContext.SavingChanges). And an override is hard-wired. An event subscription can always break somehow in code maintenance.

1
2/20/2015 11:00:42 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow