none
Problema ao usar SaveChanges() RRS feed

  • Pergunta

  • Boa tarde.

    Estou a muito tempo usando NHibernate, e agora preciso usar Entity, e estou com dificuldade para salvar um item quando este esta relacionado com outra tabela.

    Classe Produto

    public class Produto : Base
        {
            [Key]
            public int Id { get; set; }
            public string Descricao { get; set; }
            public decimal Valor { get; set; }
            public string CodigoBarras { get; set; }
            public int QtdMinimaEstoque { get; set; }
            public int QtdMaximaEstoque { get; set; }
            public DateTime DataCriacao { get; set; }
            public DateTime DataAlteracao { get; set; }     
            public virtual ProdutoTipos ProdutoTipos { get; set; }
            public virtual ProdutoUnidades ProdutoUnidades { get; set; }
        }

    Classe ProdutoTipos

    public class ProdutoTipos : Base
        {
            public ProdutoTipos()
            {
                Produtos = new List<Produto>();
            }
    
            [Key]
            public int Id { get; set; }        
            public string Descricao { get; set; }
            protected virtual ICollection<Produto> Produtos { get; set; }
    
            public new ProdutoTipos Set(ModelStateDictionary modelState)
            {
                base.Set(modelState);
                return this;
            }       
    
            public bool IsValid()
            {
                if (!ModelState.IsValid) return false;
    
                return true;
            }
        }

    A classe ProdutoUnidades é a mesma estrutura de ProdutoTipos


    Na imagem acima ele tenta salvar um produto e adicionar um registro na tabela de ProdutoTipos, eu queria apenas salvar o produto.

    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    
                modelBuilder.Entity<ProdutoTipos>().ToTable("ProdutoTipos");
                modelBuilder.Entity<ProdutoUnidades>().ToTable("ProdutoUnidades");
                modelBuilder.Entity<Produto>().ToTable("Produto");
    
                modelBuilder.Entity<Produto>()
                    .HasRequired(w => w.ProdutoTipos)
                    .WithMany()
                    .Map(m => m.MapKey("TipoId"));
    
                modelBuilder.Entity<Produto>()
                    .HasRequired(w => w.ProdutoUnidades)
                    .WithMany()
                    .Map(m => m.MapKey("UnidadeId"));

    Obrigado



    Edson de Oliveira Junior
    Analista de Sistemas Sênior
    Visite meu blog :Blog .netDescomplicado
    Linkedin : Perfil no linkedin


    terça-feira, 13 de outubro de 2015 16:57

Todas as Respostas

  • Grande Edson.

    Tudo bem? espero que sim.

    Estou meio confuso com os seus fontes de exemplo.

    Você listou as entidades ou as models?, porque eu vi um ModelState aí

    Qual abordagem que você está usando Code-First ou Fluent? pois, tá parecendo fluent.

    Me ajude a te ajudar.

    P.S.: Não se preocupe, também apanho de vez em quando do EF quando vou pro NH e de NH quando vou pro EF...



    Luis Gabriel N. Simas Arquiteto de Software

    terça-feira, 13 de outubro de 2015 19:46
  • Olá Luis, obrigado pela ajuda.

    Isso são Entidades esse ModelState ficou de uns testes que estava fazendo. A respeito de code-first ou fluent, primeiro eu criei as tabelas e depois fiz o mapeamento como nos códigos acima.


    Edson de Oliveira Junior
    Analista de Sistemas Sênior
    Visite meu blog :Blog .netDescomplicado
    Linkedin : Perfil no linkedin

    terça-feira, 13 de outubro de 2015 20:26
  • Olá Luis, obrigado pela ajuda.

    Isso são Entidades esse ModelState ficou de uns testes que estava fazendo. A respeito de code-first ou fluent, primeiro eu criei as tabelas e depois fiz o mapeamento como nos códigos acima.


    Edson de Oliveira Junior
    Analista de Sistemas Sênior
    Visite meu blog :Blog .netDescomplicado
    Linkedin : Perfil no linkedin

    Ah, tá, entendi...

    Bem, vamos por partes como já dizia jack.

    Tenta não usar o MapKey, ela pode te causar problemas como esses. Sei que muito ruim ter que apontar o Id estrangeiro na entidade, para evitar isso, você precisa estender a sua entidade principal, criar uma outra com esse Id e aí fazer relacionamento, pode parecer gambiarra, mas isso não suja a sua entidade que precisa ficar padrão para outros projetos. Eu vou te passar uma receitinha de bolo que eu tenho... Mando mais tarde pra você... eu tô no trabalho...

    Uma outra dica, tenta criar classes de configuração para você colocar seu fluent e tira do ModelBuilder, isso deixa o seu código mais compreensível até para você mesmo.

    Forte Abraço


    Luis Gabriel N. Simas Arquiteto de Software


    • Editado Gabriel Simas terça-feira, 13 de outubro de 2015 21:17 Escrevi besteira
    terça-feira, 13 de outubro de 2015 21:11
  • Opa!! Valeu pela ajuda.

    Obrigado!!


    Edson de Oliveira Junior
    Analista de Sistemas Sênior
    Visite meu blog :Blog .netDescomplicado
    Linkedin : Perfil no linkedin

    terça-feira, 13 de outubro de 2015 21:21
  • Opa!! Valeu pela ajuda.

    Obrigado!!


    Edson de Oliveira Junior
    Analista de Sistemas Sênior
    Visite meu blog :Blog .netDescomplicado
    Linkedin : Perfil no linkedin

    Não precisa agradecer... estamos no mesmo barco... hehehe...

    Luis Gabriel N. Simas Arquiteto de Software

    terça-feira, 13 de outubro de 2015 21:22
  • Minhas classes

    //Editora.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ArtigoUnity.Dominio.Entidade
    {
    	[Serializable]
    	public class Editora: EntidadeBase
    	{
    		
    		#region Atributos
    		
    		private String nome;
    
    		private ICollection<Livro> livros;
    
    		#endregion		
    
    		#region Construtores
    
    		public Editora()
    		{
    
    		}
    
    		public Editora(Nullable<long> id, String nome, ICollection<Livro> livros)
    		{
    			this.Id = id;
    			this.nome = nome;
    			this.livros = livros;
    		}        
    		#endregion
    
    		#region Propriedades
    
    		public virtual String Nome
    		{
    			get { return this.nome; }
    			set { this.nome = value; }
    		}
    
    		public virtual ICollection<Livro> Livros
    		{
    			get { return this.livros; }
    			set { this.livros = value; }
    		}
    
    		#endregion
    
    		#region Sobrescritas do Papai Object	
    	
    		public override string ToString()
    		{
    			System.Reflection.PropertyInfo[] propriedades;
    			propriedades = GetType().GetProperties(System.Reflection.BindingFlags.Public);
    			return propriedades.ToString();
    		}
    
    		#endregion  
    				
    	}
    }
    
    //Livros.cs:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ArtigoUnity.Dominio.Entidade
    {
        [Serializable]
        public class Livro: EntidadeBase
        {
            
            #region Atributos
            
            private String isbn;
            private String titulo;
            private String genero;
            private String sinopse;
            private String autor;       
            private Editora editora;       
    
            #endregion
    
            #region Construtores
            public Livro()
            {
    
            }
            public Livro(Nullable<long> id,String isbn,String titulo,String genero,String sinopse,String autor)
            {
                this.Id = id;
                this.isbn = isbn;
                this.titulo = titulo;
                this.genero = genero;
                this.sinopse = sinopse;
                this.autor = autor;
            }
    
            #endregion
    
            #region Propriedades        
    
            public virtual String Isbn
            {
                get { return this.isbn; }
                set { this.isbn = value; }
            }
    
            public virtual String Titulo
            {
                get { return this.titulo; }
                set { this.titulo = value; }
            }
    
            public virtual String Genero
            {
                get { return this.genero; }
                set { this.genero = value; }
            }
    
            public virtual String Sinopse
            {
                get { return this.sinopse; }
                set { this.sinopse = value; }
            }
    
            public virtual String Autor
            {
                get { return this.autor; }
                set { this.autor = value; }
            }
    
            public virtual Editora Editora
            {
                get { return this.editora; }
                set { this.editora = value; }
            }
            #endregion
    
            #region Sobrescritas do Papai Object        
    
            public override string ToString()
            {
                System.Reflection.PropertyInfo[] propriedades;
                propriedades = GetType().GetProperties(System.Reflection.BindingFlags.Public);
                return propriedades.ToString();
            }
    
            #endregion  
                    
        }
    }

    Meu mapeamento

    //MapeamentoEditora 
    public class MapeamentoEditora : EntityTypeConfiguration<Editora>
        {
            public MapeamentoEditora()
            {
                ToTable("Editora");
    
                HasKey(e => e.Id);
    
                Property(e => e.Nome);            
            }
    
    //MapeamentoLivro
    
    public class MapeamentoLivro: EntityTypeConfiguration<LivroId>
        {
            public MapeamentoLivro()
            {
                ToTable("Livro");
    
                HasKey(l => l.Id);
    
                Property(l => l.Autor).HasColumnName("autor").HasMaxLength(100).IsRequired();
                Property(l => l.Genero).HasColumnName("genero").HasMaxLength(100).IsRequired();
                Property(l => l.Isbn).HasColumnName("isbn").HasMaxLength(100).IsRequired();
                Property(l => l.Sinopse).HasColumnName("sinopse").HasMaxLength(500);
                Property(l => l.Titulo).HasColumnName("titulo").HasMaxLength(100).IsRequired();            
    
                HasRequired(l => l.Editora).WithMany(e =>(ICollection<LivroId>) e.Livros).HasForeignKey(l => l.IdEditora);
            }

    Se você olhar, eu tive que criar a classe LivroId, só pra colocar o Id dentro da entidade pra não sujar:

    public class LivroId: Livro
        {
            private Nullable<long> idEditora;
    
            public virtual Nullable<long> IdEditora
            {
                get { return this.idEditora; }
                set { this.idEditora = value; }
            }
    
            public LivroId(Nullable<long> id, String isbn, String titulo, String genero, String sinopse, String autor, Nullable<long> idEditora, Editora editora) :
                base(id, isbn,titulo,genero,sinopse,autor)
            {
                this.Autor = autor;
                this.Editora = editora;
                this.Genero = genero;
                this.Id = id;
                this.idEditora = idEditora;
                this.Isbn = isbn;
                this.Sinopse = sinopse;
                this.Titulo = titulo;            
            }
    
            public LivroId()
                : base()
            {
    
            }
    
            public override string ToString()
            {
                System.Reflection.PropertyInfo[] propriedades;
                propriedades = GetType().GetProperties(System.Reflection.BindingFlags.Public);
                return propriedades.ToString();
            }
    
        }

    Depois disso, eu mapeei no DbContext, observe o ModelBuilder como ficou:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
                modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
    
                modelBuilder.Configurations.Add(new MapeamentoEditora());
                modelBuilder.Configurations.Add(new MapeamentoLivro());
            }
    

    Observe os meus relacionamentos e veja se isso resolve o seu problema, rodo o CRUD numa boa.

    Segue meu Github contendo esse e outros projetos: Meu Github

    Forte Abraço.

    Qualquer dúvida avisa.


    Luis Gabriel N. Simas Arquiteto de Software

    terça-feira, 13 de outubro de 2015 21:34