Dbcontext 多数据库上下文&引用;在上一个操作完成之前,在此上下文上启动了第二个操作。”;
我一直在研究ASP.NET核心Web API。当我尝试向数据库添加新对象时,我收到“在上一个操作完成之前在此上下文上启动的第二个操作。不保证任何实例成员都是线程安全的。” 让我们展示代码: 首先,请看一下我的控制器。此控制器使用3个存储库,每个存储库使用dataContext。每个存储库的DataContext都是相同的Dbcontext 多数据库上下文&引用;在上一个操作完成之前,在此上下文上启动了第二个操作。”;,dbcontext,asp.net-core-webapi,ef-core-2.0,Dbcontext,Asp.net Core Webapi,Ef Core 2.0,我一直在研究ASP.NET核心Web API。当我尝试向数据库添加新对象时,我收到“在上一个操作完成之前在此上下文上启动的第二个操作。不保证任何实例成员都是线程安全的。” 让我们展示代码: 首先,请看一下我的控制器。此控制器使用3个存储库,每个存储库使用dataContext。每个存储库的DataContext都是相同的 public partial class TestDeviceController : BaseController { private readonly ITestD
public partial class TestDeviceController : BaseController
{
private readonly ITestDeviceRepository _testDeviceRepository;
private readonly IBridgeRepository _bridgeRepository;
private readonly IDeviceRepository _deviceRepository;
public TestDeviceController(ITestDeviceRepository testDeviceRepository, IBridgeRepository bridgeRepository, IDeviceRepository deviceRepository)
{
_testDeviceRepository = testDeviceRepository;
_bridgeRepository = bridgeRepository;
_deviceRepository = deviceRepository;
}
}
public async Task<IActionResult> Post([FromBody]TestDevicePostDTO testDevicePost)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var testDevice = new TestDeviceDTO();
Mapper.Map(testDevicePost, testDevice);
await _testDeviceRepository.Add(testDevice);
return Ok();
}
公共部分类TestDeviceController:BaseController
{
私有只读iTestDevicePository(测试设备Pository);
私有只读易趣存储库;
私有只读idevicepository(设备存储);
公共测试设备控制器(ITestDevice正测试设备正、IBridgeRepository Bridge存储库、iDeviceRecository设备正)
{
_TestDevicePository=TestDevicePository;
_bridgeRepository=bridgeRepository;
_DevicePository=DevicePository;
}
}
公共异步任务发布([FromBody]TestDevicePostDTO testDevicePost)
{
如果(!ModelState.IsValid)
返回请求(ModelState);
var testDevice=new testDeviceTo();
Map(testDevicePost、testDevice);
wait _testdeviceposition.Add(testDevice);
返回Ok();
}
正如您看到的,添加操作是从TestDevicePository调用的,因此,请查找我的TestDevicePository。现在还需要一个关于设备规格的词。它是为具有相同操作的testDevice和bridge设备创建的抽象
public class TestDeviceRepository : DeviceSpecificRepository<TestDeviceDTO, TestDevice>, ITestDeviceRepository
{
public TestDeviceRepository(DataContext dataContext, IDeviceRepository deviceRepository) : base(dataContext, deviceRepository)
{
}
public async Task Add(TestDeviceDTO testDeviceDto)
{
var device = _deviceRepository.CreateDevice(testDeviceDto).Result;
device.Type = DeviceType.TestDevice;
await CreateDeviceSpecific(testDeviceDto, device);
await _dataContext.SaveChangesAsync();
}}
公共类TestDevicePository:DeviceSpecificRecepository,ITestDevicePository
{
公共TestDevicePository(DataContext,DataContext,IDeviceRepository DevicePository):基本(DataContext,DevicePository)
{
}
公共异步任务添加(TestDeviceTo TestDeviceTo)
{
var device=_deviceposition.CreateDevice(TestDeviceTo).Result;
device.Type=DeviceType.TestDevice;
等待CreateDeviceSpecific(TestDeviceTo,设备);
wait_dataContext.saveChangesSync();
}}
在action Add中,有称为_DevicePository和DeviceSpecificPository,我认为这就是问题所在。设备存储库创建了一个上下文,TestDevicePository创建了另一个上下文
但我在Startup.cs中添加了:
services.AddDbContext<DataContext>(options => options.UseSqlServer(Configuration.GetSection("ConnectionStrings:default").Value));
services.AddScoped<IDeviceRepository, DeviceRepository>();
services.AddScoped<ITestDeviceRepository, TestDeviceRepository>();
services.AddScoped<IBridgeRepository, BridgeReporsitory>();
services.AddDbContext(options=>options.UseSqlServer(Configuration.GetSection(“connectionString:default”).Value));
services.addScope();
services.addScope();
services.addScope();
据我所知,默认的dbContext生存期是有范围的,所以应该有dbContext,因为每个请求有一个上下文。该解决方案适用于终身单例,但我希望避免保持所有时间上下文的开放性 看起来您在异步等待方法中混合了像
.Result
这样的阻塞调用
var device = _deviceRepository.CreateDevice(testDeviceDto).Result;
应该等待
public async Task Add(TestDeviceDTO testDeviceDto) {
var device = await _deviceRepository.CreateDevice(testDeviceDto);
device.Type = DeviceType.TestDevice;
await CreateDeviceSpecific(testDeviceDto, device);
await _dataContext.SaveChangesAsync();
}
同意,这是我的测试,检查解决方案是否能与同步函数调用一起正常工作。但这没用。在我的代码中,我使用的代码与您的注释中的代码相同。