In the blog post Entity Framework Core: Use TransactionScope with Caution! we saw a few cases we have to be aware of when using TransactionsScopes. Here is another one that can lead to an exception when using the new C# 8.0 feature: using declarations.

First, we look at a code snippet without C# 8.0 feature:

using (var scope = new TransactionScope())
{
   scope.Complete();
}

myDbContext.Products.ToList();

Which doesn't behave the same if we blindly apply the new C# 8.0 feature:

using var scope = new TransactionScope();

scope.Complete();

// System.InvalidOperationException: The current TransactionScope is already complete.
myDbContext.Products.ToList();

because it is not enough to Complete the TransactionScope to be able to use the underlying database connection for further queries, the TransactionScope must be disposed first. In the 2nd code snippet the ToList() is executed after Complete but before Dispose.

The corresponding code without using declaration looks like as following:

using (var scope = new TransactionScope())
{
   scope.Complete();

   // System.InvalidOperationException: The current TransactionScope is already complete.
   myDbContext.Products.ToList();
}

This may be unexpected because the TransactionScope behaves differently than the regular IDbContextTranslation started with myDbContext.Database.BeginTransaction().  So this one does not lead to an error:

using var tx = ArrangeDbContext.Database.BeginTransaction();

tx.Commit();

myDbContext.Products.ToList();

Related Articles

entity framework
Entity Framework Core 3.0 - "Hidden" GROUP BY Capabilities (Part 2)
In the previous blog post we used a navigational property to work around the limitations of the extension method . The problem is, there is not always such a property we can use for grouping. Especially, when following domain driven design practices, a bidirectional navigation is…
Pawel Gerr
entity framework
Entity Framework Core 3.0 - "Hidden" GROUP BY Capabilities (Part 1)
With Entity Framework Core 3.0 (EF) the internal implementation of the LINQ query translation has been changed a lot. So, some queries that didn't work previously are working now and some that worked are not working anymore. :) The LINQ extension method is a special one…
Pawel Gerr
entity framework
Entity Framework Core - Getting more Deadlock Information with named Transactions
Whether in an application in production or in integration tests on CI, the deadlocks are virtually unavoidable. The behavior of a deadlock depends on the database (MS SQL Server, MySQL, etc)  and the isolation level (like Snapshot Isolation). Some of the databases are blocking…
Pawel Gerr
entity framework
Entity Framework Core - Making RowNumber (more) useful
In the blog post ROW_NUMBER Support we saw how to implement a custom function and in the previous post Improved Value Conversion Support we realized that inserting and selecting custom types is one thing but using them for filtering is something totally different. Let's take a…
Pawel Gerr