问题:
我在实体框架事务中遇到回滚行为问题。我有一个场景,我要删除事务中的父实体及其子实体。但是,如果在事务提交之前发生异常,则回滚成功恢复父实体,但子实体记录仍被删除。
这是简化的代码结构:
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)也回滚?有没有更好的方法来有效处理这些场景?
我的尝试:
编辑:
我在 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);
}
}
我通过单独初始化每个表单中的 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();
}