首页 > 解决方案 > System.InvalidOperationException:将数据保存到我的数据库时

问题描述

ASP.Net 核心 blazor 应用程序。当页面首次打开时,它会从数据库中提取维修订单列表并将其显示在页面上。这很好用。

数据表有一列带有“编辑”按钮。当您编辑数据时,会弹出一个模式并显示 RO 信息供某人编辑。

我的问题是当我单击“保存”时,出现以下错误。

错误代码:

System.InvalidOperationException: '在前一个操作完成之前,在此上下文上启动了第二个操作。这通常是由使用相同 DbContext 实例的不同线程引起的,但不能保证实例成员是线程安全的。这也可能是由在客户端上评估嵌套查询引起的,如果是这种情况,请重写查询以避免嵌套调用。

值得注意的是,这个功能效果很好,我不知道我做了什么让它失败。OnInitAsync() 方法:

protected override async Task OnInitAsync()
    {
        await LoadData();        
    }

加载所有数据的方法:

protected async Task LoadData()
    {
        _repairOrders = await Task.Run(() => RepairOrderService.GetAllRepairOrders().ToArray());
        _vehicleLocations = await Task.Run(() => VehicleLocationService.GetAllLocations().ToArray());
        _repaitStages = await Task.Run(() => RepairStageService.GetAllRepairStages().ToArray());
        _employees = await Task.Run(() => EmployeeService.GetAllEmployees().ToArray());
    }

调用方法来保存数据。

protected async Task SaveRepairOrder()
    {
        if (ro.Id != 0)
        {
            await Task.Run(() =>
            {
                RepairOrderService.EditRepairOrder(ro);
            });
        }
        else
        {
            await Task.Run(() =>
            {
                RepairOrderService.CreateRepairOrder(ro);
            });
        }
        this.isAdd = false;
        await LoadData();
    }

这是我的数据访问层类中引发错误的方法。

//Get all repair order details as a list
        public List<RepairOrder> GetAllRepairOrders()
        {
            try
            {
                return db.RepairOrder.ToList();
            }
            catch
            {
                throw;               
            }
        }

问题开始后,我使 LoadData() 方法异步。谁能看到我错过了什么?

**** 更新 ******** 我更改了“services.AddSingleton();” 到“services.AddTransient();” 它似乎正在工作。我需要深入研究并尝试确定这是否是我一开始就应该这样做的方式!

标签: c#entity-frameworkblazor

解决方案


正如错误所提到的,这里发生的事情是其他一些线程已经在使用上下文,因为您的方法正在尝试使用它。

将注册更改为 Transient 是可行的,因为该实例不再共享……每次获得它时,它都会是新的……这有一些缺点,例如,如果您尝试“加入”两个实例,IQueryable<T>它将失败。 ..内存消耗也应该增加。

现在,对于您的问题,您必须调试代码流,因为显然,当您的代码输入 LoadData 方法时,先前启动的操作正在后台运行!所以“Task.Run”实际上与错误无关......如果你删除它,你应该得到同样的错误......

您可以做一些事情来验证这个假设是在加载数据之前添加大约一两秒的延迟(等待Task.Delay(2000);)......这应该足以让其他操作完成,释放上下文你的方法


推荐阅读