多个DbContext。 “在此之前的操作完成之前,第二操作在此上下文上开始。”

时间:2018-08-18 07:02:53

标签: dbcontext asp.net-core-webapi ef-core-2.0

我一直在研究ASP.NET Core Web API。我收到了“在上一个操作完成之前在此上下文上启动的第二个操作。不保证任何实例成员都是线程安全的。”当我尝试向数据库中添加新对象时。

让我们显示代码: 首先,请看一下我的控制器。该控制器使用3个存储库,每个存储库都使用dataContext。每个存储库的DataContext都相同。

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

您看到Add操作是从testDeviceRepository调用的,因此,请找到我的TestDeviceRepository。现在还需要一个有关DeviceSpecificRepository的单词。它是为具有相同操作的testDevice和网桥设备创建的抽象。

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

在操作Add中,有_deviceRepository和DeviceSpecificRepository,我认为这是问题所在。设备存储库创建了一个上下文,而testDeviceRepository创建了另一个上下文。

但是我已经添加了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>();

据我了解,默认dbContext生存期是有作用域的,因此dbContext应该存在,因为每个请求只有一个上下文。该解决方案适用于终身单例,但我想避免保持所有时间上下文为开放状态。

1 个答案:

答案 0 :(得分:0)

好像您在异步await方法中混合了.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();
}