Проблема в том, что вы передаете сущности с отношениями обратно на сервер. Каждый запрос обслуживается различным контекстом БД, поэтому, хотя ваша запись с соответствующей учетной записью и категорией выглядит как сущности, это не так. Это десериализованные объекты POCO, о которых DbContext ничего не знает. Когда вы передаете сущность, ссылающуюся на другие сущности, которые уже существуют в базе данных, получающий контекст не знает об этих сущностях, поэтому он интерпретирует их как новые записи и пытается вставить их.
Моя рекомендация по умолчанию - никогда не передавать объекты между клиентом и сервером. Это приводит к ошибкам сериализации и проблемам с производительностью от сервера к клиенту, а также подвергает вашу систему подделке, а также таким проблемам, как ошибки вставки или дублирование при использовании от клиента к серверу.
Чтобы решить вашу проблему без особых изменений:
public void AddNew(Entry entry)
{
entry.CreatedTimestamp = DateTime.Now.ToString();
var account = _context.Accounts.Single(x => x.Id = entry.Account.Id);
var category = _context.Categories.Single(x => x.Id = entry.Category.Id);
entry.Account = account;
entry.Category = category;
_context.Entries.Add(entry);
_context.SaveChanges();
}
Связывает учетную запись и категорию с экземплярами, известными по контексту.
Альтернативой может быть присоединение учетной записи и категории, переданной обратно к DbContext. Это также будет работать, однако это может сделать вашу систему уязвимой для взлома. Данные, передаваемые обратно в контроллер, могут быть перехвачены средствами отладки или анализаторами на клиентском компьютере, где данные в сообщении могут быть изменены для изменения деталей в записях и связанных с ними записях способами, которые вы не собираетесь использовать. Если по какой-либо причине какой-либо код заканчивает тем, что устанавливает эти повторно присоединенные объекты в состояние Modified, эти изменения будут сохранены в базе данных на SaveChanges. Присоединение сущностей также может создавать неудобства при работе с несколькими отдельными ссылками. Например, если вы сохраняете несколько записей одновременно с родственниками. Присоединение каждого из них будет работать нормально, когда все родственники уникальны, но без дополнительной логики проверки каждого из них на предмет наличия уже прикрепленной ссылки вы можете получить ошибки при попытке второй ссылки на уже присоединенное (или загруженное) присоединение объекта , Это означает больше кода для проверки локальной ассоциации и замены, если он найден.