Notifications for tracked changes in EntityFrameworks DbContext

.net c# entity-framework entity-framework-6 winforms


I am building a Data Entry app using Entity Framework where a user can fill out forms and then Save or Cancel. However I want the Save Button only to be enabled when there is actual data that can be saved to the database.

I know about DbContext.ChangeTracker. However I was not able to find a possibility to get a notification form the context whenever there are changes.

Of couse I could track that manually, but that is tedious and error prone.

Update The App is a WinForms Application

Question: How can I get a notification from the DbContext when it "Is Dirty/Has changes"?

Update 2

Maybe this can clarify my Question:

This is what I don't want:

using(var ctx = new DbContext()) {
  var foo = new FooEntity();
  RaiseContextIsDirty();  //<-- don't want to do this, this should be automatic
  RaiseContextIsClean();  //<-- don't want to do this, this should be automatic

What I am looking for is something like this:

using(var ctx = new DbContext()) {
  ctx.ChangeTracker.OnDirtyChanged += ContextDirtyChanged;
  var foo = new FooEntity();
  ctx.Add(foo);   //<- fires OnDirtyChanged
  ctx.SaveChanges();   //<- fires OnDirtyChanged
12/11/2015 10:47:55 PM

Popular Answer

So you could have this overridden implementation of the SaveChanges:

public class MyDbContext : DbContext
   public delegate void ChangeEventHandler(object sender, ChangeEventArgs e);
   public event ChangeEventHandler ChangeEvent;

   public override int SaveChanges()
       var result = base.SaveChanges();

       var entitiesAdded = this.ChangeTracker.Entries.Where(x => x.State == EntityState.Added);
       var entitiesRemoved = this.ChangeTracker.Entries.Where(x => x.State == EntityState.Deleted);
       var entitiesModified = this.ChangeTracker.Entries.Where(x => x.State == EntityState.Modified);

       ChangeEvent(this, new ChangeEventArgs(entitiesAdded, entitiesRemoved, entitiesModified));

       return result;


Just create a ChangeEventArgs by creating a class that implements EventArgs.

Then you should just be able to bind to the event the normal way:

ctx.ChangeEvent += (s, e) => Console.WriteLine("Changes happened");


I have just pulled most of this from MSDN, I haven't got time to test it properly. But I don't see this solution being too far wrong.

Further Thoughts

The DbSet<T> backs onto a IDbSet<T> so there is no reason why you couldn't implement your own IDbSet<T> and when you implemented your own Add function wire the events in. This would follow the same pattern as above.

Then in your MyDbContext listen to all this events and consolidate them into 1 event or handle them as they come.

9/21/2015 10:26:08 AM

Related Questions


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