none
Erro de relacionamento com Entity Framework com Mysql RRS feed

  • Pergunta

  • Olá pessoal,

    Tenho o seguinte cenário.

    Tenho a tabela Produto que tem N imagens, estou tendo erro quando tento adicionar uma nova imagem em um produto já existente. Segue o código das minhas classes:

        [Table("Products")]
        public class Product
        {
            public Product()
            {
                Images = new List<Image>();
            }
    
            [Key]
            public int Id { get; set; }
            public int CategoryId { get; set; }
    
            [Required(ErrorMessage = "Campo Nome Obrigatório")]
            [Display(Name = "Nome")]
            public string Name { get; set; }
            [Display(Name = "Preço")]
            public decimal Price { get; set; }
            [Display(Name = "Descrição")]
            public string Description { get; set; }
    
            
            public virtual IList<Image> Images { get; set; } 
    
            [ForeignKey("CategoryId")]
            public virtual Category Category { get; set; }
        }
    
        [Table("Images")]
        public class Image
        {
            [Key]
            public int Id { get; set; }
    
            [Required(ErrorMessage = "Campo Arquivo Obrigatório.")]
            public string File { get; set; }
    
            public int ProductId { get; set; }
    
            [ForeignKey("ProductId")]
            public Product Product { get; set; }
    
        }
    

    Meu DbCOntext

        public class EFDBContext : DbContext
        {
            public DbSet<Comment> Comments { get; set; }
            public DbSet<Product> Products { get; set; }
            public DbSet<Image> Images { get; set; }
            public DbSet<Category> Categories { get; set; } 
        }

    Segue o método que salva e edita o produto

    public void SaveProduct(Product product)
            {
                if (product.Id == 0)
                {
                    _context.Products.Add(product);
                }
                else
                {
                    _context.Entry(product).State = System.Data.EntityState.Modified;
                    
                }
                _context.SaveChanges();
            }

    Segue o erro que eu estou tendo.

    "A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.".

    Desde já agradeço a força.

     

     

    quarta-feira, 25 de janeiro de 2012 20:58

Respostas

  • Olá MAGAIVER!

    Tudo beleza?

    Segue uma possível solução:

     

    public void SaveProduct(Product product)
            {
                if (product.Id == 0)
                {
                    _context.Products.Add(product);
                }
                else
                {
                    _context.Entry(product).State = System.Data.EntityState.Modified;
                    foreach (var itemImage in product.Images)
                    {
                        if (itemImage.Id == 0)
                            _context.Images.Add(itemImage);
                        else
                            _context.Entry(itemImage).State = System.Data.EntityState.Modified;
                    }
                    
                }
                _context.SaveChanges();
            }


     


    Vamos ver se isso ajuda :)

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique

    quinta-feira, 26 de janeiro de 2012 12:21
    Moderador

Todas as Respostas

  • Olá,

    Fiz este teste com suas classes e inseriu:

                EFDBContext db = new EFDBContext();
     
                db.Database.CreateIfNotExists();
        
                // insere
                var pro = new Product() { Name = "Teste", Price = 10 };
                var img = new Image() { File = "arquivo.jpg", Product = pro };
     
                db.Products.Add(pro);
                db.SaveChanges();
     
                // consulta e adiciona imagem
                var dados = (from p in db.Products
                             where p.Name == "Teste"
                             select p).FirstOrDefault();
     
                var img1 = new Image() { File = "arquivo2.jpg" };
                img1.Product = dados;
                db.Images.Add(img1);
                db.SaveChanges();
    

    []s,


    Carlos dos Santos
    blog: www.carloscds.net 
    twitter: @cdssoftware

    quarta-feira, 25 de janeiro de 2012 23:39
  • Olá Carlos,

    Não consegui testar o seu código por que estou no serviço no momento, mais estava olhada ele e verifiquei que você não está atribuindo a imagem ao produto quando você salva.

    pro.Image = img;
    

    E outra coisa o erro que estou tendo é quando tento salvar o produto por exemplo:

    // consulta e adiciona imagem
                var dados = (from p in db.Products
                             where p.Name == "Teste"
                             select p).FirstOrDefault();
     
     img1.Product = dados;
    db.Products.Add(dados);
    db.SaveChanges();
    


    é neste momento que gere o erro para mim.

    Mais muito obrigado já pela força.

    quinta-feira, 26 de janeiro de 2012 11:38
  • Olá MAGAIVER!

    Tudo beleza?

    Segue uma possível solução:

     

    public void SaveProduct(Product product)
            {
                if (product.Id == 0)
                {
                    _context.Products.Add(product);
                }
                else
                {
                    _context.Entry(product).State = System.Data.EntityState.Modified;
                    foreach (var itemImage in product.Images)
                    {
                        if (itemImage.Id == 0)
                            _context.Images.Add(itemImage);
                        else
                            _context.Entry(itemImage).State = System.Data.EntityState.Modified;
                    }
                    
                }
                _context.SaveChanges();
            }


     


    Vamos ver se isso ajuda :)

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique

    quinta-feira, 26 de janeiro de 2012 12:21
    Moderador
  • Olá,

    Está aqui:

    var img1 = new Image() { File = "arquivo2.jpg" };
                img1.Product = dados;
                db.Images.Add(img1);

    []s,


    Carlos dos Santos
    blog: www.carloscds.net 
    twitter: @cdssoftware

    quinta-feira, 26 de janeiro de 2012 12:25
  • Olá Fernando,

    Cara a sua solução funcionou, apenas tive que alterar a ordem de um trecho do código, ficou assim com a alteração:

    public void SaveProduct(Product product)
            {
                if (product.Id == 0)
                {
                    _context.Products.Add(product);
                }
                else
                {
                   
                    foreach (var itemImage in product.Images)
                    {
                        if (itemImage.Id == 0)
                            _context.Images.Add(itemImage);
                        else
                            _context.Entry(itemImage).State = System.Data.EntityState.Modified;
                    }
     _context.Entry(product).State = System.Data.EntityState.Modified;
                    
                }
                _context.SaveChanges();
            }

    Como você colocou a cima estava dando a mesma exception que mencionei quando setava o valor do estado para Modified.

    Cara saberia me informar por que devo adicionar a imagem separadamente no context, o Entity Framework não consegue verificar automaticamente os filho e adicionar os valores no banco?

     

    Mais realmente muiiito obrigado pela a força, valeu mesmo.

    Forte abraço.

    sexta-feira, 27 de janeiro de 2012 01:23
  • Olá MAGAIVER!

    Esse passo é necessário pois como os dados não estavam attachados com o banco de dados, o Entry State das classes estava indicando que aquelas instâncias deveriam ser inseridas no banco de dados. Assim, o EF Code First tentava inserir registros que já estavam no banco de dados com o ID valorizado com um valor que já existia no banco de dados. Por isso dava o erro da PK.

     

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.com/
    Twitter: @ferhenrique
    sexta-feira, 27 de janeiro de 2012 10:47
    Moderador