我有一个存储过程,它根据来自不同表的值将数据写入表中。因此,它从表中读取开始/结束日期,然后创建大量数据并将其写入单独的表。
用户选择某事的开始/结束日期,然后将开始/结束日期存储到表中。然后,我从EF中调用存储过程,并且该过程从刚更新的表中读取,并填充另一个表。
如果proc失败,我想回滚proc写的所有数据,以及表的初始更新。
我认为当您拨打' SaveChanges'时,数据只写入表格(初始更新,在EF中完成)。所以我打电话给那个,然后调用程序。有没有办法检测程序是否失败,如果是,则回滚所有udpates(表更新,以及proc做的任何事情)?
目前,我的代码看起来像这样,但似乎SaveChanges中的一个paremeter无效(不需要参数),以及' AcceptAllChanges'无效:
using (var scope = new TransactionScope())
{
Context.SaveChanges(false);
Context.project_scheduled_event_payments(st.id);
Context.AcceptAllChanges();
}
答案 0 :(得分:1)
您可以使用交易范围。您需要添加对System.Transactions.dll
的引用并添加using System.Transactions;
来自msdn:
如果调用SaveChanges()或SaveChanges(true),则EF只会假设 如果它的工作完成没问题,一切都很好,所以它会 丢弃它一直在跟踪的更改,并等待新的更改。
不幸的是,如果在其他地方出现问题 交易,因为EF丢弃了它跟踪的变化,我们 无法恢复。
这是SaveChanges(false)和AcceptAllChanges()的用武之地。
SaveChanges(false)告诉EF执行必要的数据库 命令,但保持更改,以便可以重播它们 必要的。
现在,如果更广泛的交易失败,您可以重试特定的EF 位,另一次调用SaveChanges(false)。或者你可以 通过状态管理器来记录失败的内容。
一旦更广泛的交易成功,您只需致电 手动接受AcceptCllnges(),以及正在跟踪的更改 被丢弃了。
using (TransactionScope scope = new TransactionScope())
{
//Do something with context1
//Save Changes but don't discard yet
context1.SaveChanges(false);
//run your secondary procedure, if it succeeds then:
//
//
context1.AcceptAllChanges();
}
修改:好的,由于.SaveChanges(false)
是一种ObjectContext
方法(.SaveChanges(SaveOptions)
也已弃用),上述内容无效,我们有一个{{1 }}。我们知道DbContext
是DbContext
的封装,因此我们可以使用ObjectContext
来访问IObjectContextAdapter
方法:
首先,我们需要添加.SaveChanges(SaveOptions)
,然后:
using System.Data.Entity.Infrastructure;