EF Core как создать реляционную модель - PullRequest
0 голосов
/ 04 сентября 2018

Я новичок в Asp.Net Core, и мне нужно сделать следующее:

У меня есть модели curso и unidade, они имеют отношение многих ко многим.

Обе модели работают отлично, однако моя проблема в том, что я не могу создать реляционную модель.

Идея состоит в том, чтобы создать конечную точку, которая получает объект с одним unidade и массивом curso, и API будет добавлять или удалять отношения соответственно.

Следующий код - это то, что я сделал до сих пор, я получаю сообщение об ошибке Identity_Insert.

Я в правильном направлении с этим? Или есть другой лучший способ сделать это?

Modelo de curso
public class Curso
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Required]
    [Key]        
    public long curId { get; set; }

    [Required]
    [StringLength(80)]
    public string curDescricao { get; set; }

    [Required]
    [StringLength(1)]
    public string curStatus { get; set; }

    [StringLength(20)]
    public string curCodExterno { get; set; }

    [StringLength(60)]
    public string curObservacao { get; set; }
}

Modelo de unidade
public class Unidade
{        
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Required]
    [Key]
    public long uniId { get; set; }
    [Required]
    [StringLength(80)]        
    public string uniDescricao { get; set; }
    [Required]
    [StringLength(1)]
    public string uniStatus { get; set; }
    [StringLength(20)]
    public string uniCodExterno { get; set; }
    public byte[] uniImagem { get; set; }
}

Modelo de CursoUnidade
public class CursoUnidade
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Required]
    [Key]
    public long cuuId { get; set; }

    /*[Required]        
    public long cuuCurId { get; set; }
    [ForeignKey("cuuCurId")]*/        
    public List<Curso> Curso { get; set; }

    /*[Required]
    public long cuuUniId { get; set; }
    [ForeignKey("cuuUniId")]        */
    public Unidade Unidade { get; set; }
}

Serviço de unidade
public void AddTeste(CursoUnidade cursoUnidade)
{
    _contexto.Add(cursoUnidade);
    _contexto.SaveChanges();
}

1 Ответ

0 голосов
/ 04 сентября 2018

Проблема в том, что экземпляры 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();

Это решит вашу непосредственную проблему, но, как я уже говорил ранее, оно также допустит перегрузки, и, если вы явно не разрешаете это, может быть очень опасно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...