Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Entity um para muitos

Olá estou estudando a aula 5 do Curso Entity FrameWork Core, no exemplo criamos uma compra com um único produto, estou pensando como seria uma compra com 2 ou mais produtos, pensei em criar uma lista de produtos e adicionar na propriedade produto dentro de um laço e salvar no final, porém não deu muito certo. Qual seria a forma correta para realizar essa operação?

7 respostas

Olá Alberto,

se você quiser criar um relacionamento um para muitos entre duas classes, só será necessário ajustar as propriedades dos modelos para refletir esta mudança. Por exemplo, vamos supor que eu tenha as classes Livro e Escritor. Quero que cada livro tenha apenas 1 escritor, enquanto que cada escritor pode ter vários livros. As classes ficariam assim:

public class Escrito {
    public int Id { get; set; }
    public string Nome { get; set; }
    public ICollection<Livro> Livros { get; set; }
}

public class Livro {
    public int Id { get; set; }
    public string Titulo { get; set; }
    public Escritor Autor { get; set; }
}

Aí para adicionar no banco você terá que adicionar os livros dentro da lista do escrito ou passar o escritor como Autor do livro.

Obrigado pela resposta Lucas. O estranho é que no curso de Entity Framework Core aula05 diz relacionamento um para muitos e no curso ensinam de outra forma. Segue código:

public class Compra
    {
        public int Id { get; set; }
        public int Quantidade { get; internal set; }
        public int ProdutoId { get; set; }
        public Produto Produto { get; internal set; }
        public double Preco { get; internal set; }

    }

 public class Produto
    {
        public int Id { get; set; }
        public string Nome { get; set; }
        public string Categoria { get; set; }
        public double PrecoUnitario { get; set; }
        public string Unidade { get; set; }
    }


e para adicionar ensinam dessa forma:

 Produto p1 = new Produto();
                p1.Nome = "Pão Frances";
                p1.PrecoUnitario = 10.99;
                p1.Unidade = "Kg";
                p1.Categoria = "Padaria";

                var compra = new Compra();
                compra.Quantidade = 6;
                compra.Produto = p1;                
                compra.Preco = p1.PrecoUnitario * compra.Quantidade;

       contexto.Compras.Add(compra);
            contexto.SaveChanges();

Está correto desta forma também, ou este seria relacionamento um para um ?

É que essa estratégia mostrada no curso é unidirecional, ou seja, definir o mapeamento apenas de um lado. E acaba sendo um para muitos pois uma compra terá 1 produto, mas um produto poderá estar em várias compras.

A que eu mandei é uma estratégia bidirecional, ou seja, eu defino o mapeamento em ambas as pontas.

Ambas as formas são válidas, depende muito do contexto. Em geral, a pergunta que se tem que fazer é se esta classe na sua regra de negócio precisará ter acesso as informações da outra. Em geral, haverá uma classe que dependerá mais da outra e aplicamos o relacionamento nela. No exemplo do curso, com certeza uma compra precisa saber qual é o produto que está sendo comprado. Mas um produto não necessariamente estará numa compra, até por isso desta ponta não foi definido o mapeamento dado que diminui a complexidade por não precisar manipular uma lista.

Como ficaria no código que passei , adicionar dois produtos em uma mesma compra ?

solução!

A diferença ficaria em a Compra ao invés de ter uma propriedade Produto Produto ela teria uma List<Produto> Produtos. Aí para cada produto faria um compra.Produtos.Add(p1), por exemplo.

Criei o seguinte exemplo:

 var p1 = new Produto();
  p1.Nome = "sabão em pó";
...
 var compra = new Compra();
            compra.Quantidade = 1;
            compra.Preco = 3.90;
            compra.Produtos.Add(p1);

Quando eu adiciono p1 da erro de "System.NullReferenceException: 'Referência de objeto não definida para uma instância de um objeto.'

Não entendi, será que eu preciso colocar alguma coisa no construtor da classe Compra?

Desculpe, fiz uma pesquisa rápida na internet e encontrei como deve ficar meu construtor.

 public Compra()
        {
            Produtos = new List<Produto>();

        }

Agora funcionou corretamente.

Agradeço a atenção.