首先,让我提前道歉,我确定这个问题的答案存在于某个地方,但经过两个小时的搜索,我决定继续将它呈现在这里。
我有一个带有Entity Framework 6.0的C#Windows窗体应用程序。应用程序将客户记录从一个数据库迁移到另一个数据库让我们通过这个例子进行简化:table [Device]有[CustomerId]字段,它是[Customer]的一个键。[Id],它是该表的标识列。这意味着为了在[Device]中创建行,我必须首先添加到[Customer]并调用SaveChanges(),以便标识列将被播种。所以我可以帮忙[设备]。[CustomerId]。
实际的嵌套级别要复杂得多,即Customer.Device.ScheduleMode.ScheduleEntry.DeviceConfiguration。
假设问题: 迁移可能需要10-20分钟,如果用户的计算机在工作过程中崩溃,则数据库可能会损坏(不是因为它完全坏了,但在客户的记录中也是如此)现在处于“破碎状态”。我们无法在代码中处理这个问题(其中是OnSystemCrash的事件处理程序btw?lol)。
我们可以做一些事情,如声明一个"批次,"在开始工作之前将batchId写入文件。然后在崩溃恢复之后从日志文件中获取batchId并使用它从SQL服务器回滚批处理。
是否存在这样的模式,或者有人能提出另一种解决此问题的方法吗?
答案 0 :(得分:1)
看看这里:
Working with Transactions (EF6 Onwards)
在我看来,您希望在context.Database.BeginTransaction()
区块中致电using
,并在其中执行所有工作。最后,当块用完了要做的事情时,请致电Commit()
。
在using
块中,您可以包含try/catch
,在catch
中,您可以放置Rollback()
命令,以防整体操作失败。
答案 1 :(得分:0)
在您的上下文中,启动一个事务(使用Database.BeginTransaction()
),然后在结束时提交它(在返回的对象上调用Commit()
)。如果它从未提交过,它将永远不会做任何更改(如果发生崩溃),您也可以有目的地回滚它。