Inquiridor
Problema ao usar SaveChanges()

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- Editado Edson de Oliveira Junior terça-feira, 13 de outubro de 2015 17:09
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
-
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 -
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 linkedinAh, 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
-
Opa!! Valeu pela ajuda.
Obrigado!!
Edson de Oliveira Junior
Analista de Sistemas Sênior
Visite meu blog :Blog .netDescomplicado
Linkedin : Perfil no linkedin -
Opa!! Valeu pela ajuda.
Obrigado!!
Edson de Oliveira Junior
Analista de Sistemas Sênior
Visite meu blog :Blog .netDescomplicado
Linkedin : Perfil no linkedinLuis Gabriel N. Simas Arquiteto de Software
-
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
- Sugerido como Resposta Rogério dos Santos Fernandes terça-feira, 13 de outubro de 2015 21:53