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

更新Book集合项时并发错误引发异常:预期影响1行实际影响0行

问题原因及解决方案

问题根源

直接替换book.Highlights集合的操作(book.Highlights = newHighlights)会让EF Core尝试删除所有原有Highlight实体,再批量插入新实体。但连续执行移除+添加操作时,EF的变更跟踪可能出现偏差:比如原有Highlight的跟踪状态异常,或者EF生成的删除语句对应的数据库记录已不存在,导致执行删除时触发“预期影响1行实际0行”的异常。

正确的集合更新方式

不要直接替换集合,而是通过对比原有集合和DTO中的新集合,逐个处理增删改:

修改后的Highlights处理代码

case "Highlights":
{
    // 1. 找出需要删除的原有Highlight(不在新集合中的项)
    var highlightsToRemove = book.Highlights
        .Where(existing => !bookUpdateDto.Highlights.Any(dto => dto.Id == existing.HighlightId))
        .ToList();
    foreach (var highlight in highlightsToRemove)
    {
        book.Highlights.Remove(highlight);
    }

    // 2. 找出需要添加的新Highlight(不在原有集合中的项)
    foreach (var dtoHighlight in bookUpdateDto.Highlights)
    {
        var existingHighlight = book.Highlights.SingleOrDefault(h => h.HighlightId == dtoHighlight.Id);
        if (existingHighlight == null)
        {
            // 新增Highlight
            book.Highlights.Add(_mapper.Map<Highlight>(dtoHighlight));
        }
        else
        {
            // 如果需要更新已有Highlight的属性,在这里处理
            _mapper.Map(dtoHighlight, existingHighlight);
        }
    }
    continue;
}

关键说明

  • 这种方式让EF Core能正确跟踪每个实体的变更状态(删除/新增/修改),不会出现批量操作时的跟踪偏差。
  • 确保DTO中的Highlight包含唯一标识(比如Id),用于匹配原有实体和新实体。
  • 如果Highlight有需要更新的属性,通过_mapper.Map(dtoHighlight, existingHighlight)直接更新已有实体,避免重复删除插入。

额外排查点

  1. 检查Highlight实体的主键配置是否正确,EF能否正确识别唯一标识。
  2. 确认LoadRelationShipsAsync方法是否正确加载了book.Highlights集合(确保是跟踪状态的实体)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 23:33:20