我正在使用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;
}
}
}
答案 0 :(得分:0)
似乎您没有正确理解UoW。理想情况下,如果回滚该事务,则还应该处理数据库上下文。回滚应完全回滚当前的UoW。对于任何进一步的操作,您应该创建新的UoW(和数据库上下文)。当然,这不是ORM强制执行的;只是使用UoW的一种更好的方法。
实体newRecords
已在第一次调用SaveChanges
时添加到数据库竞赛中。回滚事务时,您没有处置数据库上下文。因此,该实体在上下文中仍然可用。
再次调用SaveChanges
时,您会看到一个明显的异常。
可能的解决方案:
SaveChanges
。newRecords
实体的较早实例(我不知道EF语法可以做到这一点)。对于新的重试,请创建新的实体实例,然后按原样执行步骤;即再次致电SaveChanges
。