Reputation: 6768
I am getting an exception
Microsoft.EntityFrameworkCore.Database.Transaction.AmbientTransactionWarning: An ambient transaction has been detected
but I have no Idea how to workaround this exception. My code fails, when I call SaveChanges()
inside TransactionScope
. It is probably because TransactionScope
itself is inside SQLite context
transaction, but how to handle this issue ?
Method I want to test
it uses TransactionScope, because I want to be sure, that loaded object (Request
class) will not change while I manipulate with him.
public void Handle(Create cmd)
{
// Wrap via transaction
using (var transaction = new TransactionScope(TransactionScopeOption.Required,
new TransactionOptions { IsolationLevel = IsolationLevel.RepeatableRead }))
{
// Load request object from repository.
Request request = _repository.Find(cmd.RequestId);
// Create detail object
var detail = new Detail(requestId: cmd.RequestId);
// Add created detail object into Request object
request.CreateDetail(detail);
// Save request into repository.
_repository.SaveChanges(); // <--- HERE IS THE EXCEPTION THROWN
// Commit transaction
transaction.Complete();
}
}
Test method I want to execute It uses SQLite in-memory relation database, because TransactionScope does not support non-relation database.
[Fact]
public void Create()
{
// Arrange
// ---------------------------------------------------------------------
var request = new Request();
using (var connection = new SqliteConnection("DataSource=:memory:"))
{
connection.Open();
var options = new DbContextOptionsBuilder<SamplesContext>()
.UseSqlite(connection)
.Options;
using (var context = new SamplesContext(options))
{
context.Database.EnsureCreated();
var service = SetupDetailService(context);
context.Request.Add(request);
context.SaveChanges();
var storedRequest = context.Request.FirstOrDefault();
var createCommand = new Create(requestId: Convert.ToInt32(storedRequest.Id));
// Act
// ---------------------------------------------------------------------
service.Handle(createCommand); // <--- HERE IS THE EXCEPTION THROWN
context.SaveChanges();
// Assert
// ----------------------------------------------------------------------
// ...
};
};
}
Upvotes: 3
Views: 2979
Reputation: 471
I blocked the errors to get the tests running:
var builder = new DbContextOptionsBuilder<EpsOnlineDbContext>();
DbConnection connection = new SqliteConnection("DataSource=:memory:");
connection.OpenAsync().GetAwaiter().GetResult();
builder.UseSqlite(connection);
builder.ConfigureWarnings(x => x.Ignore(Microsoft.EntityFrameworkCore.Diagnostics.RelationalEventId.AmbientTransactionWarning));
Upvotes: 7