我们正在逐步使用实体框架(4.3.1)替换传统的数据访问代码。在某些情况下,我们无法避免在一个工作单元中同时使用两种数据访问方式。理想情况下,应该在一个事务中完成。然而,旧代码使用了调用
因此,我们考虑将“旧”和“新”代码包装在
当未触发
看起来我不能使用
我知道这里有更多关于TransactionScope和SqlTransaction的帖子,但它们都(正确地)说在使用TransactionScope时不需要(也不建议)使用SqlTransaction。但在这里不使用SqlTransaction是不可选的。我们有一个遗留框架,它提交自己的
Commit()
的SqlTransaction
,而EF则管理其自己的事务。因此,我们考虑将“旧”和“新”代码包装在
TransactionScope
中。但是,在包含TransactionScope
的情况下,即使TransactionScope
未完成,提交仍会被执行。以下代码片段说明了我的问题:using (var conn = new SqlConnection("connection string"))
{
conn.Open();
using (var scope = new TransactionScope())
{
using (var tr = conn.BeginTransaction())
{
using (var cmd = conn.CreateCommand())
{
cmd.Transaction = tr;
cmd.CommandText = "some update statement";
cmd.ExecuteNonQuery();
}
tr.Commit();
}
// In reality the code above is part of a legacy DAL, immutable.
// (can't insert SaveChanges before tr.Commit).
context.SaveChanges();
if (<all ok>) // pseudo code for exception handling.
scope.Complete();
}
}
当未触发
scope.Complete()
时,更新语句仍然会被提交。看起来我不能使用
TransactionScope
来强制执行旧的数据访问代码和上下文中的SaveChanges
在一个事务中执行。或者有没有一种方法可以覆盖SqlTransaction.Commit语句?我知道这里有更多关于TransactionScope和SqlTransaction的帖子,但它们都(正确地)说在使用TransactionScope时不需要(也不建议)使用SqlTransaction。但在这里不使用SqlTransaction是不可选的。我们有一个遗留框架,它提交自己的
SqlTransaction
,并且没有api可以连接到其事务机制。