0

我正在使用一组现有的代码来管理单个事务中的多个数据库更新。这是一个简化的示例:

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 - 不希望与此相关的额外开销。

4

2 回答 2

2

使用 TransactionScope 而不是显式事务管理。您将简化整个代码,并且您所做的一切都应该自动检测和使用相同的事务。

于 2012-06-21T15:36:40.437 回答
1

有什么方法可以调用Database.GetOpenConnection()而不是CreateConnection()在你的 EL 代码中调用,并传入things.Connection你在块内创建的TransactionScope?我没有对此进行测试,但这是我首先要尝试的。

于 2012-06-21T00:00:07.390 回答