RejectChanges and DbContext

entity-framework

Question

I was working with RIA services where ObjectContext has RejectChanges() method. However, I am now working with EF 4.4 in a desktop application and I cannot find that method. So, my question is: in a scenrario where I allow user to do batch CrUD operations on collection, how would I revert all the changes? I could go with recreating the Context and fetching the data again, but that sound highly unnecessary if I need to revert changes back to 1-2 entities.

So, what is the best way to reject changes? And also, how do we know if the context is doing something (IsBusy)?

1
9
5/10/2012 3:03:31 PM

Accepted Answer

EF doesn't have any direct "reject changes" operation. You can go through entity entries in ChangeTracker / ObjectStateManager and overwrite current values with original values for modified entities. You can also detach added entities and change deleted entities back to unchanged but that all will mostly work only if you (or EF internally) didn't change the state of any independent association (relation). If you work with relations as well the whole thing can become much more complicated because you must revert relations as well - in such case it is simpler to reload data.

For reverting changes in DbContext API you can try this:

foreach (var entry in context.ChangeTracker
                             .Entries<YourEntityType>()
                             .Where(e => e.State == EntityState.Modified))
{
    entry.CurrentValues.SetValues(entry.OriginalValues);
}

In this case I think the main problem is the way how you work with entities - you allow changes on live data and EF does its logic on behind to keep data consistent when changes are performed but later on you decide that those changes will not be saved. In this case you should do one of following:

  • Discard changed data and reload whole data set (by recreating the context)
  • Separate this logic to not work on live data and push data modification to EF context only when the modification is really confirmed

Context is doing something if you say it to do something. It never becomes busy itself.

12
7/23/2013 5:08:03 PM

Popular Answer

public void RejectChanges()
        {
            foreach (var entry in ChangeTracker.Entries())
            {
                switch (entry.State)
                {
                    case EntityState.Modified:
                        {
                            entry.CurrentValues.SetValues(entry.OriginalValues);
                            entry.State = EntityState.Unchanged;
                            break;
                        }
                    case EntityState.Deleted:
                        {
                            entry.State = EntityState.Unchanged;
                            break;
                        }
                    case EntityState.Added:
                        {
                            entry.State = EntityState.Detached;
                            break;
                        }
                }
            }
        }


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