2021-01-31

EF error: A second operation started on this context before a previous asynchronous operation completed

I'm new to Blazor and working in a server-side Blazor app (.NET 5) have the following:

I have the following form:

 <EditForm Model="@MyObject" OnValidSubmit="Submit">
      <DataAnnotationsValidator />
      <ValidationSummary />

     <InputText id="name" @bind-Value="MyObject.Name" />

     <button type="submit">Submit</button>
</EditForm>

Code behind:

public MyObject MyObject { get; set; } = new MyObject();

        [Inject]
        private IMyObjectService myObjectService { get; set; }

        [Inject]
        private NavigationManager navigationManager { get; set; }

        void Submit()
        {
            var created = myObjectService.CreateMyObject(MyObject);

            if (created != null)
            {
                navigationManager.NavigateTo("myobjects/manage");
            } else
            {
                // do something
            }
        }

Repo:

private readonly ApplicationDbContext _dbContext;

public MyObjectRepo(ApplicationDbContext dbContext)
{
   _dbContext = dbContext;
}

public async Task<MyObject> CreateMyObject(MyObject MyObject)
{
   _dbContext.Add(MyObject);
   await _dbContext.SaveChangesAsync();
   return MyObject;
}

public async Task<bool> DoesMyObjectExistByName(string name)
{
    var exists = await _dbContext.MyObjects.AnyAsync(x => x.Name == name);

    if (exists) return true;
    return false;
}

I then have a MyObjectService

 private readonly IMyObjectRepo _myObjectRepo ;
    
    public MyObjectService(IMyObjectRepo myObjectRepo  )
    {
        _myObjectRepo  = myObjectRepo;
    }
    
    public async Task<MyObject> CreateMyObject(MyObject MyObject)
    {
       if (MyObject == null) throw new ArgumentNullException("MyObject cannot be null.");
    
       // THIS LINE THROWS THE EF ERROR
       var exists = await _myObjectRepo.DoesMyObjectExistByName(MyObject.Name);
    
       if (!exists)
       {
          return await _myObjectRepo.CreateMyObject(MyObject);
       } else
       {
          return null;
       }
    }

But every time I call the service to createMyObject method, EF throws an error:

Error: System.InvalidOperationException: A second operation was started on this context before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext.

In Startup.cs (.NET 5), I configure with a Transient lifetime.

services.AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("Default")),
                    ServiceLifetime.Transient);

            services.AddAutoMapper(typeof(Startup));

            services.AddScoped<IMyObjectRepo, MyObjectRepo>();

            services.AddScoped<IMyObjectService, MyObjectService>();

I think I'm using all the correct syntax for async/await and thread safety, any ideas?



from Recent Questions - Stack Overflow https://ift.tt/3coDuxw
https://ift.tt/eA8V8J

No comments:

Post a Comment