none
Oracle e EntityFramework RRS feed

  • Pergunta

  • Boa tarde pessoal,

    Tenho a seguinte situação:

      public partial class tp_procedimento
        {
            [Key, Column(Order = 0)]
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            [Editable(false)]
            [ScaffoldColumn(false)]
            public int CD_TIPO { get; set; }
    
            public string DESC_TIPO { get; set; }
    }


    Ao salvar os dados no método controller o ModelState é válido, no entanto eu faço assim:

    Recupero o último registro e adiciono + 1 na coluna CD_TIPO, o modelstate ainda está válido

                    db.TP_PROCEDIMENTO.Add(tp_procedimento);
    		try
                    {
                        db.SaveChanges(); << aqui da o erro
                    }
                    catch (Exception error)
                    {
                     

    Na linha acima acontece o erro dizendo que eu não posso inserir um valor NULO na coluna CD_TIPO, porem o campo está com valor ativo. 

    Parece que o insert está tentando passar como coluna IDENTITY (Mas no oracle não existe), já coloquei o DatabaseGeneratedOption.None, mas mesmo assim não resolve.

    Se eu conectar em base SQL SERVER o erro não acontece e ele passa o valor que esta setado.

    Para resolver o problema estou fazendo assim:

    				try
                    {
                           db.Database.ExecuteSqlCommand(" INSERT INTO TP_PROCEDIMENTO values({0},\'{1}\',\'{2}\',\'{3}\',\'{4}\') ",
                            tp_procedimento.CD_TIPO,
                            tp_procedimento.DES_TIPO,
                            tp_procedimento.SOL_NF_OBRIGATORIA,
                            tp_procedimento.SOL_NF_CLIENTE_OBRIGATORIA,
                            tp_procedimento.ATIVO);
    
                    }
    

    Mas não queria deixar assim, gostaria que funcionasse o db.SaveChanges();

    Nota: A Tabela contém primary key, e o método UPDATE com SAVECHANGES funciona normalmente é somente no Método Insert.

    Att,


    Isco Sistemas José Luiz Borges

    terça-feira, 10 de setembro de 2013 17:21

Respostas

  • No MySql, SQL Lite somente com o Identity funciona normalmente, mas bem!

    Eu andei dando uma pesquisada, você terá que continuar usando Identity, porque isso fala que o provider vai gerar a chave, e para inserir, você deve criar uma trigger que coloque a chave antes dos insert.

    1) Criar a sequence como de costume faziamos do Oracle:

    create sequence S_CD_TIPO minvalue 1 maxvalue 9999999 start with 1 increment by 1;

    2) Criar a trigger para a tabela

    create or replace trigger tp_procedimento_trigger  
    before insert on tp_procedimento for each row 
    begin 
      if :new.cd_tipo is null then select s_cd_tipo.nextval into :new.cd_tipo from dual; 
      endif; 
    end;

    Espero que ajude!





    terça-feira, 10 de setembro de 2013 21:50

Todas as Respostas

  • Boa tarde,

    Caso você queira passar a chave manualmente ao inserir um registro use:

    [Key, Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    [Editable(false)]
    [ScaffoldColumn(false)]
    public int CD_TIPO { get; set; }
    

    Caso contrário, marque a coluna como Identity que o Entity gerará o código automaticamente para inserir

    [Key, Column(Order = 0)]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Editable(false)]
    [ScaffoldColumn(false)]
    public int CD_TIPO { get; set; }
    
    Att,
    terça-feira, 10 de setembro de 2013 17:43
  • Opa..

    obrigado por responder...

    Sim, mas se usar Computed ou None   Não funciona, veja que o banco de dados é Oracle e não sql server. Logo o Identity não posso usar.

    Eu estou passando a chave manualmente, mas persiste o erro dizendo que a coluna está nula (mas não está).

    Parece que o Entity não está obedecendo o Computed ou None quando o drive é Oracle


    Isco Sistemas José Luiz Borges

    terça-feira, 10 de setembro de 2013 17:50
  • Pelo contrário, você deve usar Identity. Isso indica apenas que a chave será gerada automaticamente. O Provider de dados é quem vai tomar conta desse incremento, sendo que está usando oracle, o OleDb vai saber como gerar essa chave e devolver para o Entity.

    Dê uma lida aqui: 

    Att,

    terça-feira, 10 de setembro de 2013 20:13
  • Opa... 

    Já vi estes link, inclusive o primeiro foi muito importante para a conexão e configuração do Oracle com asp.net mvc

    Desculpe até minha persistência, mas. O Oracle ou o provider do Oracle não existe coluna Identity, eu tenho que gerar o incremento por sequence ou manualmente.

    Se eu colocar DatabaseGeneratedOption.Identity retorna o erro, pois a coluna não é passada na instrução SQL, alias se eu mudar para Identity, None ou Computed a coluna realmente não é passada na instrução usando o db.SaveChanges, eu tenho que realmente fazer assim " insert into tabela values (x,x,x,x); " caso contrário nao passa.


    Isco Sistemas José Luiz Borges

    terça-feira, 10 de setembro de 2013 20:35
  • Pelo contrário, você deve usar Identity. Isso indica apenas que a chave será gerada automaticamente. O Provider de dados é quem vai tomar conta desse incremento, sendo que está usando oracle, o OleDb vai saber como gerar essa chave e devolver para o Entity.

    Dê uma lida aqui: 

    Att,

    Só pra complementar -> isso depende muito do dataprovider existem no mercado alguns pagos que funciona uma beleza e outros que estão na minha opinião bulgados, mas, a culpa é sim do dataprovider e não do entity! tive problemas com a versão express do Oracle e seu driver próprio não incrementava os dados ai fiz muitas pesquisas e um amigo que é certificado Oracle disse que na versão final funcionava ai sinceramente fiquei sem entender! .... 

    Fúlvio Cezar Canducci Dias

    terça-feira, 10 de setembro de 2013 20:37
  • No MySql, SQL Lite somente com o Identity funciona normalmente, mas bem!

    Eu andei dando uma pesquisada, você terá que continuar usando Identity, porque isso fala que o provider vai gerar a chave, e para inserir, você deve criar uma trigger que coloque a chave antes dos insert.

    1) Criar a sequence como de costume faziamos do Oracle:

    create sequence S_CD_TIPO minvalue 1 maxvalue 9999999 start with 1 increment by 1;

    2) Criar a trigger para a tabela

    create or replace trigger tp_procedimento_trigger  
    before insert on tp_procedimento for each row 
    begin 
      if :new.cd_tipo is null then select s_cd_tipo.nextval into :new.cd_tipo from dual; 
      endif; 
    end;

    Espero que ajude!





    terça-feira, 10 de setembro de 2013 21:50
  • No MySql, SQL Lite isso funciona, mas bem!

    Eu andei dando uma pesquisada, você terá que continuar usando Identity, porque isso fala que o provider vai gerar a chave, e para inserir, você deve criar uma trigger coloque a chave antes dos insert.

    1) Criar a sequence como de costume faziamos do Oracle:

    create sequence S_CD_TIPO minvalue 1 maxvalue 9999999 start with 1 increment by 1;

    2) Criar a trigger para a tabela

    create or replace trigger tp_procedimento_trigger  
    before insert on comment for each row 
    begin 
      if :new.cd_tipo is null then select s_cd_tipo.nextval into :new.cd_tipo from dual; 
      endif; 
    end;

    Espero que ajude!


    Mysql eu nunca precisei usar!!!

    Fúlvio Cezar Canducci Dias

    terça-feira, 10 de setembro de 2013 21:55
  • Estava falando do Identity diretamente! Sem as triggers! :)
    terça-feira, 10 de setembro de 2013 22:08
  • Estava falando do Identity diretamente! Sem as triggers! :)

    Que eu saiba ele precisa criar sim!

    Não tem outra forma! porque o controle de incremento de ID é feito pelo banco e não pelo Entity Framework!


    Fúlvio Cezar Canducci Dias

    segunda-feira, 16 de setembro de 2013 12:10
  • Opa..

    Sim você está correto, quem controla o incremento é o banco, como é o oracle irei criar as triggers.



    Isco Sistemas José Luiz Borges

    segunda-feira, 16 de setembro de 2013 12:17
  • Para ter campo do tipo auto-numeração no Oracle, defina como Sequence.

    Atenciosamente, Marcio Nogueira Cardoso Pinto.

    segunda-feira, 16 de setembro de 2013 12:40