在实体框架事务发生异常期间回滚不恢复子实体记录

问题描述 投票:0回答:1

问题:

我在实体框架事务中遇到回滚行为问题。我有一个场景,我要删除事务中的父实体及其子实体。但是,如果在事务提交之前发生异常,则回滚成功恢复父实体,但子实体记录仍被删除。

这是简化的代码结构:

PaymentController.cs

try
{
  uow.BeginTransaction();
  var moneyTransaction = uow.MoneyTransactions.GetById(id);
  var log = new LogRecord(LogRecordType.Delete)
  {
    TransId = moneyTransaction.Id,
    TransType = moneyTransaction.Type,
    Data1 = moneyTransaction.Splits[0].Account.ToString(),
    Data2 = moneyTransaction.Splits[1].Account.ToString(),
    Notes = moneyTransaction.Notes,
  };
  uow.LogRecords.Add(log);
  uow.MoneyTransactions.Delete(id);
  deleted = uow.Save();
}
catch (Exception ex)
{
    uow.Rollback();
    throw ex;
}

UoW.cs

public bool Save()
{
    var saved = _context.SaveChanges();
    transaction.Commit();
    return saved > 0;
}

public void BeginTransaction()
{
    transaction = _context.Database.BeginTransaction();
}

public void Rollback()
{
    transaction.Rollback();
}

问题是回滚时Splits子实体记录没有恢复,而抛出异常时父实体MoneyTransaction成功恢复。

如何保证事务范围内发生异常时,子实体记录(Split)也回滚?有没有更好的方法来有效处理这些场景?

我的尝试:

  1. 删除行 {{ uow.LogRecords.Add(log); }} 修复回滚行为
  2. 没有UoW工作并没有解决问题。

编辑:

我在 BbContext 类中有这段代码:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Transaction>()
                .HasMany(t => t.Splits)
                .WithRequired(s => s.Transaction)
                .HasForeignKey(s => s.Transaction_Id)
                .WillCascadeOnDelete(true);

            modelBuilder.Entity<Transaction>()
                .Property(t => t.RowVersion)
                .IsRowVersion();

            base.OnModelCreating(modelBuilder);
        }
    }
c# entity-framework concurrency rollback
1个回答
0
投票

我通过单独初始化每个表单中的 DbContext 实例来解决这个问题,就像以前我只在 Program.cs 文件中初始化它并将其传递给所有程序一样,如下所示:

using (DBContext cxt = new DBContext())
{
    Application.Run(new FormLogin(cxt));
}

现在变成这样:

程序.cs

Application.Run(new FormLogin());

FormLogin.cs

public FormLogin()
{
    cxt = new DBContext();
}
© www.soinside.com 2019 - 2024. All rights reserved.