EnterpriseLibrary,EF和Transaction Scope:为什么我会看到不同的行为?

时间:2012-12-07 23:00:10

标签: entity-framework entity-framework-4.1 transactionscope

我有一个使用EnterpriseLibrary和Unity的应用,并且只在一个地方使用TransactionScope。这很好用,尽管它针对SQL Server 2005运行:

// Execute a stored proc using a DbDatabase object inserted by Unity

using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
    // Update something using the same DbDatabase object
    // Run the stored proc above, again
    // Assert that the results are different than from the previous call.
}

是的,这故意在没有scope.Complete()的情况下结束:示例来自测试。

我刚开始有另一个应用程序。它使用Entity Framework 4.1。它访问同一服务器上的同一数据库。我尝试使用TransactionScope,同时考虑“改变,验证更改,回滚更改”的想法。

using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
    using(ProjectEntities db = new ProjectEntities())
    {
         Assert.IsFalse(db.tblEntities.Any(e=>e.X == desired_value));

         db.tblEntities.Add(new tblEntity() { X = desired_value });
         db.SaveChanges();

         Assert.IsTrue(db.tblEntities.Any(e=> e.X == desired_value));

    }
}

由于非常熟悉的MSDTC未启用网络访问错误而失败。

现在,这一分钟,第一个项目的第一个测试成功,第二个测试失败。

所以我有两个问题:

  1. 有没有办法重新调整我的第二个测试,以防止事务升级到MSDTC?

  2. 有人知道为什么我从这两个框架得到不同的结果吗? EntLib是否在整个使用过程中保持单个连接分配和打开? EF会做相反的事吗?

2 个答案:

答案 0 :(得分:1)

我已经对EF,EntLib DAAB和TransactionScope进行了很多测试。

您必须考虑几点。

  • SQL Server版本
  • 连接字符串
  • EF和EntLib版本

我不记得其他组合,但是对于SQL Server 2008或更高版本,EF5和Entlib 5,您可以在同一TransactionScope中注册多个DbContexts和DAAB操作,而无需向MSDTC进行扩展。 但是有一个非常棘手的部分:

  • 连接字符串必须包含:MultipleActiveResultSets = true;
  • 连接字符串必须具有EF
  • 使用的确切格式

第二部分是最令人困惑的:当你使用连接字符串到EF时,它会改变它的格式,但是EntLib在配置文件的连接字符串中使用它。因此,您需要做的是调试代码,并记下EF使用的连接字符串的修改版本。您可以在ctx.Database.Connection.ConnectionString中找到它,其中ctx是您正在使用的DbContext。完成后,只需将连接字符串的修改版本复制并粘贴到配置文件中,EF和EntLib都将使用相同的连接字符串,因此不会升级到MSDTC。

对于以前版本的SQL Server(有时取决于EF版本),您可以找到不同的问题,但本指南可以帮助您测试您的确切设置。

答案 1 :(得分:0)

我不知道EnterpriseLibrary,但EF会为每个查询创建并打开新连接,我认为这就是您看到这些不同结果的原因。

您可以通过手动打开两个DbConnection来验证这一点。