Search code examples
c#.netwinformsentity-frameworkundo

Incomplete undo on local context with Entity Framework


I work with EF6.0 on WinForm. I have some forms which allow to add, modify or delete entities in my Sql Compact DB. As i read here : Using Local and ToBindingList for Windows Forms data binding, i use the Local property of my DbContext to perform DataBinding, which is convenient since it's an ObservableCollection (BindingSource -> BindinSourceNavigator -> DataGridView) :

this.categoryBindingSource.DataSource = Context.Categories.Local.ToBindingList();

All worked nicely, until I had to implement an Undo functionnality on those forms (users must have the hability to rollback every change since the last save). This time I used this article : Undo the changes of DbContext :

    protected virtual void Undo()
    { 
        foreach (DbEntityEntry entry in _context.ChangeTracker.Entries())
        {
            switch (entry.State)
            {
                case EntityState.Modified:
                    entry.State = EntityState.Unchanged;
                    break;
                case EntityState.Added:
                    entry.State = EntityState.Detached;
                    break;                    
                case EntityState.Deleted:
                    entry.Reload();
                    break;
                default: break;
            }
        } 
    }

When an Undo is performed, all modified entities are correctly restored, all added entities are removed but deleted entities are not restored in my Grid...

After few searches, I noticed that it's only in Local property that they are missing. "Regular" entities seems to be rollbacked correctly (State Deleted to Unchanged). So am I missing something in my Undo function ? Maybe I am obliged to manually add the restored entities to Local property in this specific case ?

Thanks for your help !


Solution

  • If you mark an entity as deleted (EntityState.Deleted) I'm surprised the documentation would state a Reload() would undo a delete. Instead, try using the same code for Modified for Delete.

            switch (entry.State)
            {
                case EntityState.Modified:
                    entry.State = EntityState.Unchanged;
                    break;
                case EntityState.Added:
                    entry.State = EntityState.Detached;
                    break;                    
                case EntityState.Deleted:
                    entry.State = EntityState.Unchanged;
                    break;
                default: break;
            }