You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多关联表更新时部分数据库实例触发DbUpdateConcurrencyException求助

问题:EF Core单API调用处理关联表新增/更新时触发并发异常

我在应用里尝试通过一次API调用更新多层关联表:

Topic | 1:1 | TopicDetails | 1:n | TopicSections

子表部分条目初始不存在,需要首次使用时创建而非更新。这个逻辑在部分数据库实例上正常,但在其他实例中抛出了并发异常。想请教:是否必须先新增条目再更新,还是有办法通过一次调用同时处理新增和更新操作?

服务处理代码

public async Task<ServiceResponse<Topic>> UpdateTopicDetails(UpdateTopicDetailsRequestDto request, string token)
{
    var serviceResponse = new ServiceResponse<Topic>() { };

    Topic? topicFromDb = await _db.Topics.FirstOrDefaultAsync(t => t.TopicId == request.TopicId);

    TopicDetails? topicDetails = topicFromDb?.Details;

    Researcher researcherFromToken = await GetResearcherFromToken(token);
            
    if (researcherFromToken == null || topicFromDb == null)
    {
        serviceResponse.Data = topicFromDb;
        serviceResponse.Messages = new List<string>() { "Unauthorized 1" };

        return serviceResponse;
    }

    if (topicDetails != null && topicDetails?.ResearcherId != researcherFromToken.ResearcherId)
    {
        serviceResponse.Messages = new List<string>() { "Unauthorized 2" };
        return serviceResponse;
    }

    List<TopicSection> sections = new() { };

    foreach(TopicSection section in request.Sections)
    {
        TopicSection sectionToAdd = new()
                {
                    SectionId = section.SectionId,
                    SectionTitle = section.SectionTitle,
                    SectionBody = section.SectionBody,
                };
        sections.Add(section);
    }

    TopicDetails topicDetailsToAdd = new()
            {
                ResearcherId = researcherFromToken.ResearcherId,
                Researcher = researcherFromToken,
                Sections = sections,
            };

    if (request.TopicDetailsId != null)
        topicDetailsToAdd.TopicDetailsId = (int)request.TopicDetailsId;

    topicFromDb.Details = topicDetailsToAdd;
    _db.Topics.Update(topicFromDb);

    bool success = _db.SaveChanges() > 0;

    if (!success)
    {
        serviceResponse.Messages = new List<string>() { "Failure " };
        return serviceResponse;
    }

    serviceResponse.Data = topicFromDb;
    serviceResponse.Success = true;

    return serviceResponse;
}

报错信息

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded.

at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyException(RelationalDataReader reader, Int32 commandIndex, Int32 expectedRowsAffected, Int32 rowsAffected)
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ConsumeResultSetWithRowsAffectedOnly(Int32 commandIndex, RelationalDataReader reader)
at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.Consume(RelationalDataReader reader)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.SqlServer.Update.Internal.SqlServerModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable1 commandBatches, IRelationalConnection connection) at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IList1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IList1 entriesToSave) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(StateManager stateManager, Boolean acceptAllChangesOnSuccess) at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.<>c.<SaveChanges>b__107_0(DbContext _, ValueTuple2 t)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func3 operation, Func3 verifySucceeded)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at SdeResearch.Api.Services.TopicService.TopicService.UpdateTopicDetails(UpdateTopicDetailsRequestDto request, String token) in C:\Users\UserName\source\repos\SdeResearch\SdeResearch.Api\Services\TopicService\TopicService.cs:line 67
at SdeResearch.Api.Controllers.TopicController.UpdateTopicDetailsAsync(UpdateTopicDetailsRequestDto request, String Authorization) in C:\Users\UserName\source\repos\SdeResearch\SdeResearch.Api\Controllers\TopicController.cs:line 125
at lambda_method85(Closure, Object)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

若需要查看调用接口的React组件、JWT令牌验证方法或其他信息,请告知。

内容的提问来源于stack exchange,提问作者Morgan Bradford

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:55:18