none
Erro ao Inserir Dados (db.SaveChanges() ) RRS feed

  • 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
    segunda-feira, 7 de abril de 2014 14:57

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


    Fulvio Cezar Canducci Dias

    segunda-feira, 7 de abril de 2014 15:07
  • 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!!!


    Fulvio Cezar Canducci Dias

    segunda-feira, 7 de abril de 2014 21:31

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


    Fulvio Cezar Canducci Dias

    segunda-feira, 7 de abril de 2014 15:07
  • 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

    segunda-feira, 7 de abril de 2014 15:44
  • 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!!!


    Fulvio Cezar Canducci Dias

    segunda-feira, 7 de abril de 2014 21:31
  • Entendi... Valew


    Isco Sistemas José Luiz Borges

    quarta-feira, 9 de abril de 2014 11:59