c# - 为什么 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 的记录...
解决方案
请AsNoTracking()
在从数据库中检索数据时使用。EF 在更新实体时跟踪 PK。在您执行以下方法时
await _sandwichRepository.GetByIdAsync(item)
你可以举个例子
_context.Set<item>().AsNoTracking().FirstOrDefault(a=> a.id = item.id).
推荐阅读
- python - Python稀疏矩阵乘法
- r - 重新编码嵌套在 (100k+) 个用户 ID 中的(不相等数量的)日期
- django - 如何在 django 模板中从 for 循环中转义一行
- android - 通过蓝牙经典在 Android 中进行 SSL 握手
- python - 错误:(gcloud.beta.ai-platform.versions.create)参数版本:必须指定
- javascript - JavaScript - 变量的数学运算
- javascript - Reactjs 中的 setState 不是函数
- python - 为什么我的 python 没有正确安装,即使我没有错误?
- javascript - 在输入的检查状态下更改标签背景
- intellij-idea - 如何告诉 intellij 在失败的命令上恢复宏执行?