【发布时间】:2022-08-19 16:51:14
【问题描述】:
我正在使用一个非常标准的通用存储库模式(例如https://codewithmukesh.com/blog/repository-pattern-in-aspnet-core/#What_would_happen_if_we_didnt_have_an_UnitOfWork_Abstraction)
在程序.cs我将我的通用存储库服务定义为范围。
services.AddScoped(typeof(IGenericRepository<,>), typeof(GenericRepository<,>));
在工作服务中,我在代码执行期间创建了两个作用域实例;
using (var serviceScope = _serviceProvider.CreateScope())
{
var personDataService = serviceScope.ServiceProvider.GetRequiredService<IGenericRepository<Person, MyDbContext>>();
var auditLogDataService = serviceScope.ServiceProvider.GetRequiredService<IGenericRepository<AuditLog, MyDbContext>>();
...
}
例如,当我在第一个服务上生成 SQL 异常的调用时,我想在第二个服务中记录错误;
try {
await personDataService.InsertAsync(myNewPerson);
}
catch (Exception ex)
{
var newAuditLog = new AuditLog(\"Exception occurred inserting a new user\", ex);
await auditLogDataService.InsertAsync(newAuditLog);
}
但是,当personDataService 生成SQLException 时,例如;
SqlException:无法将值 NULL 插入列 \'Name\'\"
然后
catch块触发,当我在第二个auditLogDataService服务上运行InsertAsync()时再次遇到相同的错误。SqlException:无法将值 NULL 插入列 \'Name\'\"
似乎第一个服务的更改也在第二个服务中。我假设
MyDbContext是共享的。如何创建
auditLogDataService的独立实例,这样我就可以在没有第一个更改的情况下保存第二个更改?
-
请不要将存储库模式与实体框架一起使用。它已经通过 DbSet<T> 公开了一个存储库。你将如何支持 Include()s?投影(选择)?分组?但是,如果您将存储库注册为瞬态,它们应该获得自己的 DbContext 实例,而您不应该遇到遇到的问题。请显示minimal reproducible example,包括您的 DI 设置。
-
也许最简单的解决方案是为日志记录创建一个单独的上下文。无论如何,我认为这不是一个坏主意。在应用程序中保持分离。这允许您为一个工作单元拥有一个共享(范围)上下文。
-
@CodeCaster 当然,但问题是关于 DI 配置。我的问题很好,准备充分。