回滚交易

时间:2019-07-19 06:04:18

标签: entity-framework-6 repository-pattern

我正在使用SQLite数据库。当事务回滚时,我不会处理数据库上下文。事务回滚后。再次插入与事务中插入的实体类型相同的实体(已回滚的实体)会引发以下异常。重现该错误的步骤:

STEP 1.交易开始:

_transaction = _dbContext.Database.BeginTransaction();

STEP 2.插入记录:

_dbContext.EntityName.Add(newRecords);

STEP 3.保存更改:

_dbContext.SaveChanges();

第4步:回滚交易:

_transaction.Rollback();
_transaction.Dispose();
_transaction = null;

步骤5:重复步骤1,2,3。 STEP 3抛出上面提到的异常

注意-_dbContext未处理。

InvalidOperationException:保存或接受更改失败,因为多个“ EntityName”类型的实体具有相同的主键值。确保显式设置的主键值是唯一的。确保在数据库和实体框架模型中正确配置了数据库生成的主键。将实体设计器用于数据库优先/模型优先配置。使用“ HasDatabaseGeneratedOption”流利的API或“ DatabaseGeneratedAttribute”进行代码优先配置。

表格设计

public partial class Student
{
    public InstrumentMaster()
    {
        Subject = new HashSet<Subject>();
    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int StudentId { get; set; }
    public string StudentName { get; set; }

    public ICollection<Subject> Subject { get; set; }
}

 public partial class Subject
{
    public Subject()
    {

    }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int SubjectId { get; set; }
    public int? SubjectName { get; set; }
    public int? StudentId { get; set; }

    public Student Student { get; set; }
}

在回滚交易期间,我还将清除跟踪的实体。

 public static void UndoingChangesDbContextLevel(DbContext _dbContext)
    {
        foreach (DbEntityEntry entry in _dbContext.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;
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

似乎您没有正确理解UoW。理想情况下,如果回滚该事务,则还应该处理数据库上下文。回滚应完全回滚当前的UoW。对于任何进一步的操作,您应该创建新的UoW(和数据库上下文)。当然,这不是ORM强制执行的;只是使用UoW的一种更好的方法。

实体newRecords已在第一次调用SaveChanges时添加到数据库竞赛中。回滚事务时,您没有处置数据库上下文。因此,该实体在上下文中仍然可用。

再次调用SaveChanges时,您会看到一个明显的异常。

可能的解决方案:

  • 回滚事务时处理数据库上下文。
  • 请勿再次致电SaveChanges
  • 在回滚后重新尝试之前,请删除newRecords实体的较早实例(我不知道EF语法可以做到这一点)。对于新的重试,请创建新的实体实例,然后按原样执行步骤;即再次致电SaveChanges