EF5 Code First TransactionScope无需升级到MSDTC

时间:2012-11-27 19:57:00

标签: c# .net entity-framework transactionscope

我首先使用EF5代码,我需要在同一个事务中包含多个SaveChanges()的调用。我对使用transactionScope相对较新,似乎无法调整其上的选项来完成我想要做的事情。

以下代码驻留在一个服务类中,该服务类注入了我的DbContext类的实例。我不会在这个类的任何地方创建额外的DbContext实例。

起初我尝试了以下内容。代码很干净,但它会尝试在SaveChanges函数的GenerateInvoice方法中升级到DTC。

using (var scope = new TransactionScope())
{
    // This function does some work and calls SaveChanges
    Guid invoiceId = GenerateInvoice(cart);  

    // This function also does some querying and calls SaveChanges
    DeleteCart();

    // Transaction should only commit if both functions above were successful
    scope.Complete();

}

我做了一些研究,并将代码更改为以下内容,但不会升级到DTC,但我不确定它是否是最好的方法。

IObjectContextAdapter adapter = (IObjectContextAdapter)_context;

adapter.ObjectContext.Connection.Open();

using (var scope = new TransactionScope())
{

    // This function does some work and calls SaveChanges
    Guid invoiceId = GenerateInvoice(cart);  

    // This function also does some querying and calls SaveChanges
    DeleteCart();

    // Transaction should only commit if both functions above were successful
    scope.Complete();

    adapter.ObjectContext.Connection.Close();

}

是否有更简单的方法可以首先在多个SaveChanges中使用EF5代码获得事务支持而不升级到DTC?

由于

1 个答案:

答案 0 :(得分:2)

不是我找到的。它也是有道理的。通过不止一次调用SaveChanges(),您可能会打开与数据库的多个连接。跨这些连接协调事务的唯一方法是使用分布式事务(因此MSDTC)。

我能想出的最佳解决方案是只拨打SaveChanges()一次。这可能意味着重构一些代码,但最好是所有需要事务的实体都同时提交。

仅调用SaveChanges()一次也允许EF更改跟踪器使用其缓存并在应用程序和数据库之间保存大量通信。