Usuário com melhor resposta
Erro ao Inserir Dados (db.SaveChanges() )

Pergunta
-
Bom dia Pessoal, estou com uma dúvida(erro) e não consigo sair dela....
Vejam só:
Meu Modelo de Dados
public partial class Cadastro { [Key, Column(Order = 0)] public int cd_cadastro { get; set; } public string razao { get; set; } public virtual Cliente Cliente { get; set; } } public partial class Cliente { [Key, Column(Order = 0)] public int cd_cadastro { get; set; } public string operacao_fiscal { get; set; } } --- relacionamento na Entities protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Cadastro>().HasRequired(a => a.Cliente).WithRequiredPrincipal().WillCascadeOnDelete(true); /// aqui já não sei se está certo /// o relacionamento é 1 para 1 sendo que o /// cadastro é a tabela PAI } public partial class CadCli { public virtual Cadastro Cadastro { get; set; } public virtual Cliente Cliente { get; set; } }
Na minha view create (GET) está assim @model CadCli
No Meu Controller esta assim:
[HttpPost]
public ActionResult Create(Cadastro cadastro, Cliente cliente) { /// todos os campos de cadastro, vem preenchido normalemnte /// Aqui esta Valido if (ModelState.IsValid) { cadastro.cd_cadastro = 1 // teste db.Cadastro.Add(cadastro); // aqui não entra, pois esta FALSE if (cadastro.ind_cliente) { cliente.cd_cadastro = cadastro.cd_cadastro; db.Cliente.Add(cliente); } // Aqui esta o problema db.SaveChanges(); // Mesmo não entrando na linha ind_cliente // ele faz o insert do cadastro (OK) // mas tb faz um insert do cliente // e não deveria, pois eu não adicionei // o cliente em db.Cliente.Add(cliente) /// me parece que teria que ter algo assim // "não adicione o cliente que esta no CadCli " }
Eu não quero que faça o insert do Cliente, pois tem uma condição dizendo se Insere ou Não..., mas mesmo assim ele faz o insert...
Mas quando indica TRUE na condição tenho que inserir
como sair dessa ?
Isco Sistemas José Luiz Borges
- Editado Jose Luiz Borges segunda-feira, 7 de abril de 2014 14:59 falta de info
Respostas
-
Relacionamento 1 para 1:
Siga os Exemplos:
http://msdn.microsoft.com/en-us/data/jj591620.aspx
http://fulviocanducci.wordpress.com/2013/08/13/operaes-crud-no-entity-framework/
Só para te alertar o 1 para 1 seria assim nas classes (estou simulando)
public partial class Cadastro { [Key, Column(Order = 0)] public int cd_cadastro { get; set; } public string razao { get; set; } } public partial class Cliente: Cadastro { public string operacao_fiscal { get; set; } }
Entendeu, então o seu modelo não está normalizado corretamente
- Marcado como Resposta Jose Luiz Borges quarta-feira, 9 de abril de 2014 11:59
-
Eu fiz um exemplo de como você deveria fazer?
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ConsoleApplication2.Models { [Table("Cadastro")] public partial class Cadastro { [Key] public int cd_cadastro { get; set; } [Required] public string razao { get; set; } } } namespace ConsoleApplication2.Models { [Table("Cliente")] public partial class Cliente: Cadastro { [Required] public string operacao_fiscal { get; set; } } } namespace ConsoleApplication2.Models { public class Contexto: DbContext { public Contexto() :base("Data Source=.\\sqlexpress;Initial Catalog=SuperBanco;Persist Security Info=True;User ID=sa;Password=senha;MultipleActiveResultSets=True;Application Name=EntityFramework1") { } public DbSet<Cadastro> Cadastro { get; set; } } }
Assim seria a maneira que acredita você queira utilizar ...
Usando:
using ConsoleApplication2.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { using (Contexto db = new Contexto()) { //modo cliente e cadastro Cliente cliente = new Cliente(); cliente.razao = "Razão 3"; cliente.operacao_fiscal = "3"; //modo somente cadastro Cadastro cadastro = new Cadastro(); cadastro.razao = "Razão Sem Cliente 3"; db.Cadastro.Add(cliente); db.Cadastro.Add(cadastro); db.SaveChanges(); } } } }
ai você deve ta me perguntando, como Cadastro.Add(Cliente), é porque Cliente é Herança de Cadastro e por isso consigamos gravar dados referentes a herança, mas, não sendo obrigatório no segundo que só vai gravar Cadastro ...
Para Recuperar
using ConsoleApplication2.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { using (Contexto db = new Contexto()) { Cliente cliente = db.Cadastro.OfType<Cliente>().Where(x => x.cd_cadastro == 2).FirstOrDefault(); Cadastro cadastro = db.Cadastro.Where(x => x.cd_cadastro == 3).FirstOrDefault(); } } } }
Então perceba que para recuperar Cliente você deve informar a Cadastro pelo método OfType o tipo que deve retornar ... (o legal que você pode recuperar qualquer item que herda de Cadastro, eu tenho esse modelo no último site que fiz e fico perfeito) ...
Bom qualquer dúvida ... tamos ai!!!
- Marcado como Resposta Jose Luiz Borges quarta-feira, 9 de abril de 2014 11:59
Todas as Respostas
-
Relacionamento 1 para 1:
Siga os Exemplos:
http://msdn.microsoft.com/en-us/data/jj591620.aspx
http://fulviocanducci.wordpress.com/2013/08/13/operaes-crud-no-entity-framework/
Só para te alertar o 1 para 1 seria assim nas classes (estou simulando)
public partial class Cadastro { [Key, Column(Order = 0)] public int cd_cadastro { get; set; } public string razao { get; set; } } public partial class Cliente: Cadastro { public string operacao_fiscal { get; set; } }
Entendeu, então o seu modelo não está normalizado corretamente
- Marcado como Resposta Jose Luiz Borges quarta-feira, 9 de abril de 2014 11:59
-
Opa obrigado por responder
public partial class Cliente: Cadastro { public string operacao_fiscal { get; set; } }
Fiz o relacionamento como mencionado nos link; e fiz a classe cliente assim, como me passou
mas estouraram outros erros:
No Index ele retorna que a coluna operacao_fiscal não existe, no Create eu não consigo recuperar as informações do Model...
Existe como usar como esta é desmarcar o cliente para não inserir no banco ?
tentei algo assim:
if (nao_insere_cliente)
db.Entry(cliente).State = EntityState.Unchanged;
mas tb da erro
Isco Sistemas José Luiz Borges
-
Eu fiz um exemplo de como você deveria fazer?
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace ConsoleApplication2.Models { [Table("Cadastro")] public partial class Cadastro { [Key] public int cd_cadastro { get; set; } [Required] public string razao { get; set; } } } namespace ConsoleApplication2.Models { [Table("Cliente")] public partial class Cliente: Cadastro { [Required] public string operacao_fiscal { get; set; } } } namespace ConsoleApplication2.Models { public class Contexto: DbContext { public Contexto() :base("Data Source=.\\sqlexpress;Initial Catalog=SuperBanco;Persist Security Info=True;User ID=sa;Password=senha;MultipleActiveResultSets=True;Application Name=EntityFramework1") { } public DbSet<Cadastro> Cadastro { get; set; } } }
Assim seria a maneira que acredita você queira utilizar ...
Usando:
using ConsoleApplication2.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { using (Contexto db = new Contexto()) { //modo cliente e cadastro Cliente cliente = new Cliente(); cliente.razao = "Razão 3"; cliente.operacao_fiscal = "3"; //modo somente cadastro Cadastro cadastro = new Cadastro(); cadastro.razao = "Razão Sem Cliente 3"; db.Cadastro.Add(cliente); db.Cadastro.Add(cadastro); db.SaveChanges(); } } } }
ai você deve ta me perguntando, como Cadastro.Add(Cliente), é porque Cliente é Herança de Cadastro e por isso consigamos gravar dados referentes a herança, mas, não sendo obrigatório no segundo que só vai gravar Cadastro ...
Para Recuperar
using ConsoleApplication2.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { using (Contexto db = new Contexto()) { Cliente cliente = db.Cadastro.OfType<Cliente>().Where(x => x.cd_cadastro == 2).FirstOrDefault(); Cadastro cadastro = db.Cadastro.Where(x => x.cd_cadastro == 3).FirstOrDefault(); } } } }
Então perceba que para recuperar Cliente você deve informar a Cadastro pelo método OfType o tipo que deve retornar ... (o legal que você pode recuperar qualquer item que herda de Cadastro, eu tenho esse modelo no último site que fiz e fico perfeito) ...
Bom qualquer dúvida ... tamos ai!!!
- Marcado como Resposta Jose Luiz Borges quarta-feira, 9 de abril de 2014 11:59
-