撤消实体框架实体中的更改
这可能是一个微不足道的问题,但是:由于ADO.NET实体框架自动跟踪更改(在生成的实体中)并因此保留原始值,因此我如何回滚对实体对象所做的更改?
我有一个允许用户在网格视图中编辑一组“客户”实体的表单。
现在我有两个按钮“接受”和“恢复”:如果单击“接受”,我调用Context.SaveChanges()
并将更改的对象写回数据库。 如果单击“恢复”,我希望所有对象都能获得其原始属性值。 那会是什么代码?
谢谢
EF中没有恢复或取消更改操作。 每个实体在ObjectStateEntry
中都有ObjectStateManager
。 状态条目包含原始值和实际值,因此您可以使用原始值来覆盖当前值,但必须为每个实体手动执行。 它不会对导航属性/关系的变化表示敬意。
“恢复更改”的常见方式是处理上下文并重新加载实体。 如果您想避免重新加载,您必须创建实体克隆并在新的对象上下文中修改这些克隆。 如果用户取消更改,您仍将拥有原始实体。
为脏项目查询DbContext的ChangeTracker。 将已删除的项目状态设置为未更改并将项目添加到已分离。 对于修改的项目,请使用原始值并设置条目的当前值。 最后将修改条目的状态设置为不变:
public void RollBack()
{
var context = DataContextFactory.GetDataContext();
var changedEntries = context.ChangeTracker.Entries()
.Where(x => x.State != EntityState.Unchanged).ToList();
foreach (var entry in changedEntries)
{
switch(entry.State)
{
case EntityState.Modified:
entry.CurrentValues.SetValues(entry.OriginalValues);
entry.State = EntityState.Unchanged;
break;
case EntityState.Added:
entry.State = EntityState.Detached;
break;
case EntityState.Deleted:
entry.State = EntityState.Unchanged;
break;
}
}
}
dbContext.Entry(entity).Reload();
致MSDN:
重新加载数据库中的实体用数据库中的值覆盖任何属性值。 调用此方法后,实体将处于“未更改”状态。
请注意,通过请求恢复到数据库有一些缺点:
上一篇: Undo changes in entity framework entities
下一篇: How to get id from entity for Auditlog in Entity Framework 6