如何在EF4中为多个ObjectContexts实现单个SQL事务

时间:2012-10-17 02:56:15

标签: c# entity-framework

我有一个相当大的数据库,其中包含为不同业务模块创建的表。

我们决定分别为不同的模块创建不同的edmx文件。

但是,在尝试为将要写入不同edmx中的多个表的逻辑操作实现TransactionScope时,如何防止使用MSDTC?同样,底层数据库是相同的,我不想在这种情况下使用MSDTC。

有没有办法通过活动事务传递已打开的SQL连接?

提前感谢您的帮助。

此致 威廉

2 个答案:

答案 0 :(得分:2)

TransactionScope在数据库不同和/或连接字符串不同时登记MSDTC。

Rick Strahl对此有一个great article(他的观点是LINQ to SQL,但它适用于EF)。钱款:

  

TransactionScope是一个高级的Transaction包装器   真正容易将任何代码包装到事务中而无需跟踪   手动交易。传统上,TransactionScope是一个.NET   分布式事务协调器(DTC)周围的包装器,但它是   功能有所扩展。一个问题是DTC是   在资源使用方面相当昂贵,它需要   DTC服务实际上是在机器上运行(还有另一项服务   这对客户端安装尤其麻烦。)

     

但是,最近对TransactionScope和SQL Server客户端进行了更新   驱动程序使得可以使用TransactionScope类和易用性   只要您在运行,就可以使用它而不需要DTC   针对单个数据库并使用单个一致连接   串。在上面的示例中,由于事务与a一起使用   DataContext的单个实例,事务实际上有效   不涉及DTC。这是在SQL Server 2008中。

另请参阅此SO question/answer,其中我找到了Rick博客的链接。

因此,如果您要连接到同一个数据库并使用相同的连接字符串,则不应涉及DTC。

答案 1 :(得分:0)

感谢上面的所有回复!

顺便说一句,只是设法找到一个明确使用EntityConnection和EntityTransaction的解决方案。样本是这样的:

    string theSqlConnStr = "data source=TheSource;initial catalog=TheCatalog;persist security info=True;user id=TheUserId;password=ThePassword";

    EntityConnectionStringBuilder theEntyConnectionBuilder = new EntityConnectionStringBuilder();
    theEntyConnectionBuilder.Provider = "System.Data.SqlClient";
    theEntyConnectionBuilder.ProviderConnectionString = theConnectionString;
    theEntyConnectionBuilder.Metadata = @"res://*/";

    using (EntityConnection theConnection = new EntityConnection(theEntyConnectionBuilder.ToString()))
    {
        theConnection.Open();
        theET = null;

        try
        {
            theET = theConnection.BeginTransaction();

            DataEntities1 DE1 = new DataEntities1(theConnection);
            //DE1 do somethings...

            DataEntities2 DE2 = new DataEntities2(theConnection);
            //DE2 do somethings...

            DataEntities3 DE3 = new DataEntities3(theConnection);
            //DE3 do somethings...

            theET.Commit();
        }
        catch (Exception ex)
        {
            if (theET != null) { theET.Rollback(); }
        }
        finally
        {
            theConnection.Close();
        }
    }

明确使用EntityConnection& EntityTransaction,我可以为单个数据库实现多个ObjectContexts的单一连接和事务共享,但不需要使用MSDTC。

希望此信息有用。 Gd运气!!