并发DbContext访问是否属于拥有范围的解决方案?

问题描述 投票:0回答:1

当同一类的两个实例试图使用使用存储库的相同方法时,我在单例服务中遇到此错误

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.
   at Npgsql.EntityFrameworkCore.PostgreSQL.Update.Internal.NpgsqlModificationCommandBatch.ConsumeAsync(RelationalDataReader reader, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(DbContext _, ValueTuple`2 parameters, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IReadOnlyList`1 entriesToSave, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)

为了解决此问题,我在Autofac中找到了使用自有范围的解决方案

private readonly Func<Owned<IProductRepository>> productRepositoryFactory;
...
using (var repositoryOwned = productRepositoryFactory())
{
   await repositoryOwned.Value.DeleteRangeAsync(idsToRemove);
}

这解决了问题,但恐怕由于创建和处置DbContext的垃圾邮件(使用的DbContext根据依赖项进行注册),性能会受到影响。是否有更好的解决方案,不会以这种方式影响性能?

c# entity-framework entity-framework-core autofac npgsql
1个回答
0
投票

创建范围是一种更好的方法。例如,您可以将DI用于IServiceProvider serviceProvider,然后像这样使用它:

 using (var scope = _serviceProvider.CreateScope())
 {
     var service = scope.ServiceProvider.GetRequiredService<IYOURSERVICE>();
     ...
 }
© www.soinside.com 2019 - 2024. All rights reserved.