Проблема в том, что экземпляры Curso
и Unidade
на передаваемом входе CursoUnidade
не отслеживаются EF. В результате, когда вы пытаетесь добавить его и сохранить, он пытается снова создать эти два объекта. Однако, поскольку у них обоих уже есть идентификаторы, он не может этого сделать и не работает.
Это одна из многих проблем, связанных с попыткой сохранить то, что было передано в ваши действия напрямую. Вы должны использовать модель представления, а затем отобразить ее поверх фактического объекта, который вы в итоге сохраните. Это заставляет вас быть откровенным о том, что вы делаете, и приводит к меньшему количеству ошибок, таких как эта. Кроме того, если вы на самом деле не хотите, чтобы два связанных экземпляра могли быть изменены в то же время, когда они связаны, нет смысла публиковать всю сущность в любом случае. Это может легко привести к эксплойту, когда пользователь вносит изменения в сущности, которые он не должен делать, и из-за небрежного обращения на стороне сервера после публикации они просто слепо сохраняются в базе данных.
Вместо этого используйте вид модели / DTO, например:
public class CursoUnidadeDTO
{
public long CursoId { get; set; }
public long UnidadeId { get; set; }
}
Тогда в вашем действии:
public void AddTeste(CursoUnidadeDTO cursoUnidade)
{
var curso = await _contexto.Cursos.FindAsync(cursoUnidade.CursoId);
var unidade = await _contexto.Unidades.FindAsync(cursoUnidade.UnidadeId);
if (curso == null || unidade == null)
{
return BadRequest("Cannot create relationship");
}
_contexto.Add(new CursoUnidade { Curso = curso, Unidade = unidade });
await _contexto.SaveChangesAsync();
}
Или, если у вашего CursoUnidade
класса есть явные свойства внешнего ключа, вам даже не нужно ничего искать:
_contexto.Add(new CursoUnidade { CursoId = cursoUnidade.CursoId, UnidadeId = cursoUnidade.UnidadeId });
Кроме того, вы можете сначала просто присоединить эти объекты, чтобы EF знал о них:
_contexto.Attach(cursoUnidade.Curso);
_contexto.Attach(cursoUnidade.Unidade);
_contexto.Add(cursoUnidade);
await _contexto.SaveChangesAsync();
Это решит вашу непосредственную проблему, но, как я уже говорил ранее, оно также допустит перегрузки, и, если вы явно не разрешаете это, может быть очень опасно.