Mar*_*ner 110 .net entity-framework rollback
这可能是一个微不足道的问题但是:由于ADO.NET实体框架会自动跟踪更改(在生成的实体中)并因此保留原始值,我如何回滚对实体对象所做的更改?
我有一个表单,允许用户在网格视图中编辑一组"客户"实体.
现在我有两个按钮"Accept"和"Revert":如果单击"Accept",我会调用Context.SaveChanges()并将更改的对象写回数据库.如果单击"恢复",我希望所有对象获取其原始属性值.那个代码是什么?
谢谢
Tah*_*ooy 146
查询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;
        }
    }
 }
Lad*_*nka 69
EF中没有恢复或取消更改操作.每个实体都有ObjectStateEntry在ObjectStateManager.状态条目包含原始值和实际值,因此您可以使用原始值覆盖当前值,但必须手动为每个实体执行此操作.它不会反映导航属性/关系的变化.
"还原更改"的常用方法是处理上下文和重新加载实体.如果要避免重新加载,则必须创建实体克隆并在新对象上下文中修改这些克隆.如果用户取消更改,您仍将拥有原始实体.
Lu5*_*u55 30
dbContext.Entry(entity).Reload();
加密到MSDN:
从数据库重新加载实体,使用数据库中的值覆盖任何属性值.调用此方法后,实体将处于Unchanged状态.
请注意,将请求还原到数据库有一些缺点:
小智 17
这对我有用:
dataContext.customer.Context.Refresh(RefreshMode.StoreWins, item);
item要还原的客户实体在哪里.
sal*_*uce 13
虽然这个问题早于 Entity Framework Core,但 EF Core 开发人员已经为这个问题提供了一个简单的解决方案。
从 EF Core 5.0 开始,ChangeTracker现在提供了一种清除跟踪实体的方法,该方法比分离所有更改的实体更有效。
context.ChangeTracker.Clear()
停止跟踪所有当前跟踪的实体。
DbContext 被设计为具有较短的生命周期,其中为每个工作单元创建一个新实例。这种方式意味着当上下文在每个工作单元结束时被处理时,所有跟踪的实体都将被丢弃。但是,在创建新上下文实例不切实际的情况下,使用此方法清除所有跟踪的实体可能会很有用。
这种方法应该始终优先于分离每个被跟踪的实体。分离实体是一个缓慢的过程,可能会产生副作用。此方法在从上下文中清除所有跟踪的实体方面更加有效。
请注意,此方法不会生成 StateChanged 事件,因为实体不是单独分离的。
此时,您可以从 中检索原始值DbContext。
Gui*_*ish 12
轻松的方式,无需跟踪任何变化 它应该比查看每个实体更快.
public void Rollback()
{
    dataContext.Dispose();
    dataContext= new MyEntities(yourConnection);
}
// Undo the changes of all entries. 
foreach (DbEntityEntry entry in context.ChangeTracker.Entries()) 
{ 
    switch (entry.State) 
    { 
        // Under the covers, changing the state of an entity from  
        // Modified to Unchanged first sets the values of all  
        // properties to the original values that were read from  
        // the database when it was queried, and then marks the  
        // entity as Unchanged. This will also reject changes to  
        // FK relationships since the original value of the FK  
        // will be restored. 
        case EntityState.Modified: 
            entry.State = EntityState.Unchanged; 
            break; 
        case EntityState.Added: 
            entry.State = EntityState.Detached; 
            break; 
        // If the EntityState is the Deleted, reload the date from the database.   
        case EntityState.Deleted: 
            entry.Reload(); 
            break; 
        default: break; 
    } 
} 
它对我有用.但是,您必须从上下文重新加载数据以带来旧数据.来源于此
| 归档时间: | 
 | 
| 查看次数: | 81343 次 | 
| 最近记录: |