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

EF7插入重复键报错后,修改条码重提交仍触发相同异常求助

解决EF Core上下文保留错误实体导致重复键异常的问题

问题原因

EF Core的DbContext内置状态跟踪机制,第一次添加的Barcode为"aa"的Position实体已经被上下文标记为Added状态。即使后续创建了新的实体,之前的错误实体仍在上下文的追踪列表中,调用SaveChangesAsync时会尝试提交所有追踪的变更,因此重复抛出唯一键冲突异常。

解决方案

1. 在异常处理中移除错误实体的追踪

修改通用仓储的Add方法,捕获DbUpdateException后,将出错的实体从上下文的状态追踪中分离:

public virtual async Task<int> Add(TDto dto)
{
    var entity = _mapper.Map<TEntity>(dto);
    SetNavigationPropertiesToNull(entity);
    var entry = _db.Set<TEntity>().Add(entity);
    
    try
    {
        await _db.SaveChangesAsync();
        return entity.Id;
    }
    catch (DbUpdateException)
    {
        // 将错误实体从上下文追踪中移除
        _db.Entry(entity).State = EntityState.Detached;
        throw; // 重新抛出异常,让上层UI处理错误提示
    }
}

2. 确保上下文的短生命周期

虽然你已将DataContext配置为Transient,但需确认仓储服务的生命周期也为Transient,保证每次操作都获取全新的上下文实例,避免复用带有错误实体的上下文:

// Program.cs中配置仓储(示例)
builder.Services.AddTransient<IRepository<Position, PositionDto>, Repository<Position, PositionDto>>();

3. 提前验证唯一性(减少异常触发)

在执行Add操作前,先查询数据库检查Barcode是否已存在,提前拦截重复值,提升用户体验(注意:此方法无法完全避免并发冲突,数据库唯一索引仍是最终保障):

public virtual async Task<int> Add(TDto dto)
{
    var entity = _mapper.Map<TEntity>(dto);
    
    // 针对Position实体的Barcode唯一性检查
    if (entity is Position position)
    {
        var isDuplicate = await _db.Set<Position>()
            .AnyAsync(p => p.Barcode == position.Barcode);
        
        if (isDuplicate)
        {
            throw new InvalidOperationException($"条码 {position.Barcode} 已存在");
        }
    }
    
    SetNavigationPropertiesToNull(entity);
    _db.Set<TEntity>().Add(entity);
    await _db.SaveChangesAsync();
    return entity.Id;
}

4. 清空所有追踪实体(极端场景)

如果上下文存在多个错误追踪实体,可在异常后清空所有追踪状态(谨慎使用,避免影响正常操作):

catch (DbUpdateException)
{
    foreach (var entry in _db.ChangeTracker.Entries())
    {
        entry.State = EntityState.Detached;
    }
    throw;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:40:07