title: TransactionScope + NHIbernate multiple sessions
body: <p>im writing database related tests, but they take long time to complete and im trying to speed them up..</p>
  
  <p>my current code looks like this:</p>
  
  <pre><code>[TestClass]
  public class TestClass
  {
      private const string ConnectionString = "...";
      private const string TemplateDatabaseBackupPath = "...";
  
      [ClassInitialize]
      public static void ClassInitialize(TestContext context) {
          InitializeTestEnviroment(); // create &amp; fill db, init internals
  
          using (SqlConnection connection = new SqlConnection(ConnectionString)) {
              connection.Open();
              using (SqlCommand command = connection.CreateCommand()) {
                  command.CommandText = "BACKUP DATABASE [Testing] TO DISK = @path";
                  command.Parameters.AddWithValue("path", TemplateDatabaseBackupPath);
                  command.ExecuteNonQuery();
              }
          }
      }
  
      [TestCleanup]
      public static void TestCleanup() {
          using (SqlConnection connection = new SqlConnection(ConnectionString)) {
              connection.Open();
  
              using (SqlCommand command = connection.CreateCommand()) {
                  command.CommandText = "ALTER DATABASE [Testing] SET SINGLE_USER WITH ROLLBACK IMMEDIATE";
                  command.ExecuteNonQuery();
              }
  
              using (SqlCommand command = connection.CreateCommand()) {
                  command.CommandText = @"RESTORE DATABASE [Testing] FROM DISK = @path WITH REPLACE";
                  command.Parameters.AddWithValue("path", TemplateDatabaseBackupPath);
                  command.ExecuteNonQuery();
              }
          }
      }
  
      [TestMethod]
      public void TestMethod() {
           Entity entity = new Entity { Name = "Fred Flindstone" };
           BlackBox.UpdateEntity(entity, 42);
  
           Entity actual = BlackBox.GetEntityById(42);
           Assert.AreEqual("Fred Flindstone", actual.Name);
      }
  
      [TestMethod]
      public void TestMethod2() {
           Entity entity = new Entity { Name = "Fred Flindstone" };
           BlackBox.UpdateEntity(entity, 42); // 42 = entity id
  
           Entity actual = BlackBox.GetEntityById(42);
           Assert.AreEqual("Fred Flindstone", actual.Name);
      }
  }
  
  // NH mapping class
  public class Entity {
      public int Id;
      public string Name;
  }
  
  // Not real code - just to get the idea how CRUD are performed internally,  this code cannot be easily changed (no unit tests for it)
  public static class BlackBox {
      public static void UpdateEntity(object entity, int id) {
          using(var s = GetSession()){
              s.Update(id, entity);
          }
      }
  
      public static void GetEntityById(int id) {
          using(var s = GetSession()){
              return s.Session.Query&lt;Entity&gt;().Single(o =&gt; o.Id == Id);
          }
      }
  
      private static IHiberSession GetSession(){ 
          return ...; // not relevant
      }
  
      public interface IHiberSession {
          ISession Session { get; }
          ...
      }
  }
  </code></pre>
  
  <p>after some mesumenents i found this:</p>
  
  <pre><code>ClassInitialize                8s
  TestMethod and TestMethod2     ~20ms
  TestCleanup                    3s
  </code></pre>
  
  <p>obviously i would like to reduce TestCleanup time ...</p>
  
  <p>after some searching i found System.Transactions.TransactionScope and thought i have a winner:</p>
  
  <pre><code>[ClassInitialize]
  public static void ClassInitialize(TestContext context) {
      InitializeTestEnviroment();
  }
  
  [TestInitialize]
  public static void TestInitialize() {
      _Scope = new System.Transactions.TransactionScope();
  }
  
  [TestCleanup]
  public static void TestCleanup() {
      _Scope.Dispose(); // Rollback any changes made by test
  }
  </code></pre>
  
  <p>with should be faster than database restore but unfortunately
  i get this exception during in session Close() method</p>
  
  <pre><code>System.InvalidOperationException: Disconnect cannot be called while a transaction is in progress.
  </code></pre>
  
  <p>with seems to be related to this closed issue: <a href="https://nhibernate.jira.com/browse/NH-1744" rel="nofollow noreferrer">NH-1744</a> but that dont give me any idea, gow to fix my code :(</p>
  
  <p>Anyway my question is how to make this code to work:</p>
  
  <pre><code>void TestMethod() {
      using(var scope = new System.Transactions.TransactionScope()) {
  
          // these two usings cannot be changed ...
          using (ISession session = GetSession()) {
               // some CRUD
          }
  
          using (ISession session = GetSession()) {
              // some more CRUD
          }
      }
  }
  </code></pre>
  
  <p>or any other idea, how to make database fast backup/restore? (in-memory backup would be nice)</p>
  
  <p>PS: TransactionScope is used ONLY in unit testing, 'live' code is scopeless</p>
  
  <p>Thanks for any help ...</p>