简体   繁体   English

实体框架回滚

[英]Entity Framework Rollback

I'm having Issues with entity framework using transactions and ASP MVC, for example, if at some point during the transaction an exception is thrown, the DbContext remains outdated because the rollback did not return the navigation collection to its original state. 我在使用事务和ASP MVC的实体框架方面遇到问题,例如,如果在事务期间的某个时刻引发异常,则DbContext仍会过时,因为回滚未将导航集合返回到其原始状态。

Entity Framework version: 6.1 实体框架版本:6.1

Related model: 相关型号:

public Action {
    public int Id;
    public string property;
}

Main Model: 主要型号

public Model1 {
   public int Id;
   public virtual ICollection<Action> Actions
}

and the try/catch block to rollback 和try / catch块回滚

//There is only one instance of DbContext, and is shared with all controllers and models
DbContext context = GetSingletonContext();
DbContextTransaction transaction = context.Database.BeginTransaction();    

Model1 instance = null;
try
{
    instance = context.Model1.Find(31);
    instance.Actions.Remove(instance.Actions.First());
    throw new ExceptionOfAnyKind();
    context.SaveChanges();
    transaction.Commit();
}
catch (Exception)
{
    transaction.Rollback();
    throw;
}

I did something like this to 'clear' the entity tracker, so the next time Entity Framework theorically will use the database, but i'm not sure if this can lead to some kind of issues in other actions of controllers that should be being used at the same time: 我做了这样的事情来“清除”实体跟踪器,因此下一次实体框架理论上将使用数据库,但是我不确定这是否会导致应该使用的控制器的其他动作中的某些问题与此同时:

var entities = (from entity in entityManager.ChangeTracker.Entries() select entity).ToList();
foreach (var item in entities)
{
    item.State = EntityState.Detached;
}

My question is, how can i ensure that even when an error is thrown, the DbContext is always updated or returned to the previous state, or if there is a way to force the reload of navigation collections of a single model instance. 我的问题是,如何确保即使引发错误,DbContext也始终会更新或返回到以前的状态,或者是否有办法强制重新加载单个模型实例的导航集合。

already tried this: 已经尝试过这个:

var entry = context.Entry<Model1>(instance).Collection("Actions");
entry.IsLoaded = false;
entry.Load();

and this one just reload properties of the model, but no the navigation properties 这只是重新加载模型的属性,但没有导航属性

var objectContext = ((IObjectContextAdapter)context).ObjectContext;
objectContext.Refresh(RefreshMode.StoreWins, instance);

same as previous: 与之前相同:

var entry = context.Entry<Model1>(instance);
entry.Reload();

When using AsNoTracking, the instance has the correct values, but cannot be updated or deleted until attached to the context, and if already an entity with the same PK an exception is thrown 使用AsNoTracking时,该实例具有正确的值,但是在附加到上下文之前无法更新或删除,并且如果已经具有相同PK的实体,则引发异常

You can use code transactions, instead of database transactions. 您可以使用代码事务而不是数据库事务。 And using using statements to dispose of dbcontext. 并使用using语句处理dbcontext。

using (TransactionScope scope = new TransactionScope())
{
    using (MyDBContext db = new MyDBContext())
    {
       //...
       db.SaveChanges()
    }
       scope.Complete();
    }

    using (MyDBContext db = new MyDBContext())
    {
       //...
       db.SaveChanges()
    }
       scope.Complete();
    }

/* end of adding transaction scope*/
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM