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();