0

我有一个使用 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(): 的情况下结束:示例来自测试。

我还有一个刚刚开始的应用程序。它使用实体框架 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做相反的事情吗?

4

2 回答 2

1

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

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

于 2012-12-07T23:02:51.300 回答
1

我对 EF、EntLib DAAB 和 TransactionScope 做了很多测试。

您必须考虑到几点。

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

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

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

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

对于 SQL Server 的早期版本(有时取决于 EF 版本),您可能会发现不同的问题,但本指南可以帮助您测试您的确切设置。

于 2013-04-29T08:42:14.660 回答