views:

49

answers:

2

Hi gurus, i have a Customer class which includes a Contact class that stores all the contacts for that particular customer, so they are linked with a foreign key relationship.

Here is my scenario: the user Edits the customer's info including the contacts, and then decides to hit the "Cancel" button. The contacts are bound to a grid so everytime an edit/add/delete is made it automatically updates the Contact entity in the cached database context. So how can i rollback all the changes made by the user to the Contact entity?

I tried the following (after searching google for answers):

    public static void CustomerRollback(Customer customer)
    {
        dbContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, customer);
        dbContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, customer.Contacts);
    }

But that didn't work. Any other ideas? Please note that my problem is only with rolling back the Contacts entity. I guess what's causing the issue in the first place is that the grid automatically updates the cached entities. So when i try to cancel, the EntityState for each contact has already changed to a modified state (EntityState.Added, EntityState.Deleted, etc.). Do i need to loop through the contacts and check their EntityState property and do something with it?

Thanks Caesar

+1  A: 

Take a look at the AcceptAllChanges method. SaveChanges(SaveOptions) can also be helpful.
One more solution is to use the ObjectContext instance as Unit Of Work and to create it for an operation, and to save changes only when necessary (when user confirms that it is necessary) just disposing the context in another case - this will discard the changes made to the context.

Devart
But if i dispose the context then i'll have to re-fetch all the data back again for the rest of the application...that would be bad.I will google your suggestion about the Unit of Work.Thanks
Caesar
A: 

So here is what i did, which is a workaround trick from Entity Framework 1.0, i was hoping that EF 4.0 has a much simpler way to rollback the object context. Please share with me if you know of a better way, this seems to work for the time being:

        // delete added objects that did not get saved
        foreach (var entry in dbContext.ObjectStateManager.GetObjectStateEntries(EntityState.Added))
        {
            if (entry.Entity != null)
                dbContext.DeleteObject(entry.Entity);
        }
        // Refetch modified objects from database
        foreach (var entry in dbContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))
        {
            if (entry.Entity != null)
                dbContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, entry.Entity);
        }
        // Recover modified objects that got deleted
        foreach (var entry in dbContext.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted))
        {
            if (entry.Entity != null)
                dbContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, entry.Entity);
        }

        dbContext.AcceptAllChanges();
Caesar