代码之家  ›  专栏  ›  技术社区  ›  J.G.Sable

EF错误:在上一个异步操作完成之前,在此上下文上启动了第二个操作

  •  0
  • J.G.Sable  · 技术社区  · 4 年前

    我是Blazor的新手,在服务器端Blazor应用程序(.NET 5)中工作时有以下几点:

     <EditForm Model="@MyObject" OnValidSubmit="Submit">
          <DataAnnotationsValidator />
          <ValidationSummary />
    
         <InputText id="name" @bind-Value="MyObject.Name" />
    
         <button type="submit">Submit</button>
    </EditForm>
    

    代码隐藏:

    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
        }
    }
    

    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;
    }
    

    然后我有一个 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;
       }
    }
    

    错误:System.InvalidOperationException异常:第二次操作失败 在上一个操作完成之前在此上下文上启动。这是 通常由不同线程同时使用同一个 DbContext的实例。

    services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("Default")),
            ServiceLifetime.Transient);
    
    services.AddAutoMapper(typeof(Startup));
    services.AddScoped<IMyObjectRepo, MyObjectRepo>();
    services.AddScoped<IMyObjectService, MyObjectService>();
    

    我想我使用了所有正确的语法来保证异步/等待和线程安全,有什么想法吗?

    0 回复  |  直到 4 年前
        1
  •  0
  •   atiyar    4 年前

    我不熟悉 Blazor 我自己,但我认为 Submit 方法应该是-

    async void Submit()
    {
        var created = await myObjectService.CreateMyObject(MyObject);
    
        if (created != null)
        {
            navigationManager.NavigateTo("myobjects/manage");
        } else
        {
            // do something
        }
    }
    

    基本上,您缺少async/await关键字。