我正在使用一组现有的代码来管理单个事务中的多个数据库更新。这是一个简化的示例:
Database db = DatabaseFactory.CreateDatabase();
using (DbConnection dbConnection = db.CreateConnection())
{
dbConnection.Open();
DbTransaction dbTransaction = dbConnection.BeginTransaction();
try
{
//do work
dbTransaction.Commit();
}
catch (Exception ex)
{
dbTransaction.Rollback();
}
}
我也在同一个项目中使用 EntityFramework 进行新开发。下面是使用我的存储库类的简化示例:
List<ThingViewModel> things = new List<ThingViewModel>();
// populate list of things
IObjectRepository thingRepository = new ThingRepository();
thingRepository.AddThings(things);
thingRepository.Save();
我希望在“AddThings”中完成的工作作为第一个代码块中事务的一部分发生。
是否有一些干净的方法可以将我的存储库模式混合到现有代码中,反之亦然?我还没有到可以将现有代码重写为完全在 EntityFramework 中的地步,所以我正在寻找一些临时方法。
我尝试将事务从旧代码传递到存储库,从而传递到 EntityFramework,但这似乎不起作用。我还尝试将 ObjectContext 传递回旧代码,以便将其加入事务中。这两种方法都不起作用。
我不敢相信我是第一个在将现有代码迁移到 EntityFramework 时遇到这个障碍的人......一定有一些我没有考虑的事情。
我将在下面列出我尝试过的事情:
using (TransactionScope transactionScope = new TransactionScope())
{
Database db = DatabaseFactory.CreateDatabase();
using (DbConnection dbConnection = db.CreateConnection())
{
dbConnection.Open();
DbTransaction dbTransaction = dbConnection.BeginTransaction();
try
{
//do work
dbTransaction.Commit();
}
catch (Exception ex)
{
dbTransaction.Rollback();
}
}
Thing thing = new Thing(){
Prop1 = Val1,
Prop2 = Val2
};
ThingObjectContext context = new ThingObjectContext();
context.Things.AddObject(thing);
context.SaveChanges();
transactionScope.Complete();
}
最后一个示例“有效”,它不能用作事务。当 EF 插入失败时,TransactionScope 不会回滚 EL 命令。如果我不对 .Commit() 和 .SaveChanges() 进行这些显式调用,则什么也不会发生。如果可能的话,我真的希望它能够共享相同的连接。我目前正在使用的另外两个变体是尝试在 EF 和 EL 之间使用相同的连接,以及在一侧或另一侧使用 EnlistTransaction。绝对试图阻止它成为 MSDTC - 不希望与此相关的额外开销。