首页 > 解决方案 > 为什么 EF Core 尝试使用现有 ID 创建新记录以及如何解决?

问题描述

我正在使用 .NET 5 上的 ASP.NET Core 开发 RESTful API。当我尝试使用 EF Core 向数据库添加新记录时,出现以下错误:

System.InvalidOperationException:无法跟踪实体类型“订单”的实例,因为已在跟踪另一个具有键值“{Id:2}”的实例。

堆栈跟踪表明此错误发生在我的AddAsync方法上的服务类中。它看起来像这样:

public async Task<OrderResponseDto> AddAsync(OrderRequestDto requestDto)
{
    var newOrder = _mapper.Map<Order>(requestDto);
    newOrder.Items = new List<Sandwich>();

    foreach (var item in requestDto.IdsOfOrderedSandwiches)
    {
        var sandwich = await _sandwichRepository.GetByIdAsync(item);
        newOrder.Items.Add(sandwich);
    }

    var createdOrder = await _orderRepository.AddAsync(newOrder);
    return _mapper.Map<OrderResponseDto>(createdOrder);
}

存储库类中的AddAsync方法如下所示:

public virtual async Task<T> AddAsync(T entity)
{
    await _dbContext.Set<T>().AddAsync(entity);
    await _dbContext.SaveChangesAsync();
    return entity;
}

(我删除了一些检查,它们只会抛出异常。)

我有一个播种器类,它添加了两个订单,ID 为 1 和 2。因此,我希望 EF Core 创建一个 ID 为 3 的新实体。但是,从上面的异常中可以看出:它尝试创建新记录ID 2 已经存在。

现在,我有以下问题:为什么 EF Core 会尝试这样做,我该如何解决这个问题?我只是希望它创建一个 ID 为 3 的记录...

标签: c#asp.net-coreentity-framework-core

解决方案


AsNoTracking()在从数据库中检索数据时使用。EF 在更新实体时跟踪 PK。在您执行以下方法时

await _sandwichRepository.GetByIdAsync(item)

你可以举个例子

_context.Set<item>().AsNoTracking().FirstOrDefault(a=> a.id = item.id).

推荐阅读