Я понял, в чем проблема. Поскольку я использовал Truncate, чтобы стереть данные, он сбрасывал последовательность автоинкремента на 1. Порядок # 1 уже был в ChangeTracker после усечения, и когда он пошел на вставку другого ордера, БД возвратила первичный ключ '1', который уже присутствовал в ChangeTracker. Последующие вызовы могут обновить средство отслеживания изменений, но ваша сущность все еще находится там в состоянии «добавлено», несмотря на исключение, и в будущем при вызове этой же записи и вызове SaveChanges теперь будут вставлены две повторяющиеся записи.
Хотя я могу избежать этого состояния, не сбрасывая последовательности, нет простого способа предотвратить запуск EF в этом состоянии. Я думаю, что поведение должно состоять в том, чтобы перезаписать запись в Changetracker в состоянии «Добавлено», а не генерировать исключение. Исключение не содержит ключ, который находился в конфликте, потому что он был получен с сервера, поэтому нет хорошего способа программно с ним справиться.
По крайней мере, я могу удалить его из changeTracking, если SaveChangesAsync () не может предотвратить появление повторяющихся строк в будущем.
public async Task<Order> CreateAsync(Order order)
{
_dbContext.OrderBook.Add(order);
try
{
await _dbContext.SaveChangesAsync();
}
catch(DbUpdateException ex)
{
_dbContext.OrderBook.Remove(order);
throw ex;
}
return order;
}