In my ASP.NET Core app I have DbContext that contains two types of Entities, say, Pupils and Classes. I want to add a new Class, get the Id of new Class and add a new Pupil to the class. I tried to do it this way:
var Class = new Class{ name = "Math" };
Context.Classes.Add(Class);
await Context.SaveChangesAsync();
var Pupil = new Pupil{ name = "Rem", ClassId = Class.Id };
Context.Pupils.Add(Pupil);
await Context.SaveChangesAsync();
However I got the error on the second call to SaveChangesAsync():
Microsoft.EntityFrameworkCore.DbContext:Error: An exception occurred in the database while saving changes. System.InvalidOperationException: A second operation started on this context before a previous operation completed. Any instance members are not guaranteed to be thread safe.
I tried to wrap everything in transaction this way:
using (var transaction = Context.Database.BeginTransaction()) {
....
transaction.Commit();
}
But the problem persists.
What is the correct way to perform two related operations in EF Core? Is it possible to do in a single transaction?
PS: I'm using PostgreSQL with Npgsql provider
The problem was with using DB somewhere else since ASP.NET Core Dependency Injection creates only single instance of each service. I solved it by creating a new scope
public MyService(IServiceProvider provider) { ... };
....
var Scope = provider.CreateScope();
var Context = Scope.ServiceProvider.GetService<ShellDbContext>();
Is Class.Id
is autoincrement/sequence field? May be EF is querying DB for it's value after insertion... Try add Console.WriteLine(Class.Id)
or await Context.Entry(Class).ReloadAsync()
after first save.