繁体   English   中英

.NET Core Entity Framework - 异步写入数据库

[英].NET Core Entity Framework - asynchronous writting into database

我有个问题。 我有 ASP .NET Core REST API 应用程序,在一种方法中,我正在尝试将更多更改异步写入数据库中。每次将不同数量的对象写入数据库时​​,以及每次发生三个不同错误之一时。任何建议都可以是错的?

这是我的代码:

启动文件

public void ConfigureServices(IServiceCollection services)
{
...
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connection_string), ServiceLifetime.Transient);
services.AddScoped<IHelper, Helper>();
...
}

Helper.cs

private MyDbContext _dbContext;
public Helper(IOptions<HelperSettings> settings, ILogger<Helper> logger, MyDbContext dbContext)
{
    ...
        _dbContext = dbContext;
    ...
}

public void Save(object entity)
{
    ...
        _dbContext.Add(entity);
}

这是控制器和引发异常的方法。

public class MyController : ControllerBase
{
private readonly Helper _db;

public MyController(IHelper helper)
{
      _db = helper;
}
...

[HttpPost]
[Route("something")]
[Produces("application/json")]
public async Task<ActionResult<Guid>> CreateSomethingAsync([FromBody] DataRequest data)
{
    ...
          if (data.Answers != null)
          {
                List<Task> saveTasks = new List<Task>();

                foreach (AnswerData ans in data.Answers)
                {
                    Answer answer = ans.ConvertToAnswer(); //just create new Answer instance and filll it with data from AnswerData
                    saveTasks.Add(Task.Run(() => _db.Save(answer)));
                }

                await Task.WhenAll(saveTasks);
                await _db.DbContext.SaveChangesAsync();
          }
          return Ok(...);
}
}

我在另一个应用程序的循环中调用CreateSomethingAsync() 它抛出以下三个异常之一:

System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'

或者

System.InvalidOperationException: 'Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.'

或者

System.InvalidOperationException: Cannot start tracking InternalEntityEntry for entity type 'Answer' because another InternalEntityEntry is already tracking the same entity

在线_dbContext.Add(entity); 在我的Helper.cs

我知道问题出在并行性上,但我不知道如何解决。 有任何想法吗?

DbContext 不是线程安全的(这就是您得到的异常告诉您的),并且调用DbContext.Set<T>.Add()不会花费大量时间。 通过并行化Add()不会将多个实体异步添加到数据库中 - 您只是在调用SaveChanges()时将实体标记为要添加的

因此,虽然我确信您有理由并行化_db.Save(answer)调用,但它可能没有任何性能改进,因此您可以完全删除它,序列化工作。

如果您在那里所做的工作确实受益于并行化,只需将调用DbContext.Set<T>.Add()移出那里 - 它不是线程安全的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM