DbContext和RejectChanges

Gor*_*ran 9 entity-framework

我正在使用RIA服务,其中ObjectContext有RejectChanges()方法.但是,我现在正在桌面应用程序中使用EF 4.4,我找不到该方法.所以,我的问题是:在我允许用户对收集进行批量CrUD操作的场景中,我将如何恢复所有更改?我可以继续重新创建Context并再次获取数据,但如果我需要将更改恢复为1-2个实体,那么这听起来非常不必要.

那么,拒绝变更的最佳方法是什么?而且,我们如何知道上下文是否正在做某事(IsBusy)?

Lad*_*nka 12

EF没有任何直接的"拒绝更改"操作.您可以在ChangeTracker/中查看实体条目,ObjectStateManager并使用修改实体的原始值覆盖当前值.您还可以分离添加的实体并将已删除的实体更改回未更改但仅当您(或内部EF)未更改任何独立关联(关系)的状态时,所有实体才会起作用.如果你也处理关系,整个事情会变得复杂得多,因为你必须恢复关系 - 在这种情况下,重新加载数据会更简单.

要恢复DbContext API中的更改,您可以尝试这样做:

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

在这种情况下,我认为主要的问题是你如何使用实体 - 你允许对实时数据进行更改,而EF会在后面执行逻辑,以便在执行更改时保持数据一致,但稍后您决定不会保存这些更改.在这种情况下,您应该执行以下操作之一:

  • 丢弃已更改的数据并重新加载整个数据集(通过重新创建上下文)
  • 将此逻辑分开,不对实时数据起作用,只有在确实修改了修改后才将数据修改推送到EF上下文

如果你说它做某事,上下文正在做一些事情.它永远不会变得忙碌.


Ser*_*lov 11

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;
                        }
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)