none
Update com linq to Sql não funciona... RRS feed

  • Pergunta

  • Olá PessoALL,

    Sou iniciante e estou "apanhando" para fazer um update utilizando linq...

    Tenho o seguinte cenário:

    CAMADA DAO

    namespace ProjetoSistema.DAO
    {
        interface IPessoaDAO
        {
            
            void AtualizarPessoa(TbPessoas objPessoa);

        }
    }

     

    ainda na camada DAO

    namespace ProjetoSistema.DAO
    {
        public class PessoaDAO : IPessoaDAO
        {
            DCProjetoSistemaDataContext dc;

            public PessoaDAO()
            {
                dc = new DCProjetoSistemaDataContext();
            }

           
            #region Membros de IPessoaDAO


            public void AtualizarPessoa(TbPessoas objPessoa)
            {
                TbPessoas atualizar = dc.TbPessoas.Where(
                    p => p.IdPessoa.Equals(objPessoa.IdPessoa)).First();
               
                dc.SubmitChanges();
            }

            #endregion
        }
    }

     

    Na camada UI tenho o form com o botão btnAtualizar com o seguinte evento:

    private void btnAtualizar_Click(object sender, EventArgs e)
            {
                TbPessoas atualizar = new TbPessoas()
                {
                    IdPessoa = Convert.ToInt32(txtIdPessoa.Text),
                    IdTipoPessoa_Pes = Convert.ToInt32(cboIdTipoPessoa.SelectedValue),
                    Sexo_Pes = sexo_PesTextBox.Text,
                    Nome_Pes = nome_PesTextBox.Text,
                    Apelido_Pes = apelido_PesTextBox.Text,
                    CpfCnpj_Pes = mtxCpfCnpj.Text,
                    RgIe_Pes = rgIe_PesTextBox.Text,
                    OrgEmissor_Pes = orgEmissor_PesTextBox.Text,

                    Funcionario_Pes = funcionario_PesCheckBox.Checked,
                    Cliente_Pes = cliente_PesCheckBox.Checked,
                    Fornecedor_Pes = fornecedor_PesCheckBox.Checked,
                    AceitaEmail_Pes = chbAceitaEmail.Checked,
                    Fabricante_Pes = fabricante_PesCheckBox.Checked,
                    Ativo_Pes = ativo_PesCheckBox.Checked,

                    Email_Pes = email_PesTextBox.Text,

                    CEP_Pes = mtxCEP.Text,
                    Logradouro_Pes = txtLogradouro.Text,
                    ComplementoLogradouro_Pes = txtComplemento.Text,
                    NumeroLogradouro_Pes = txtNumero.Text,
                    Localidade_Pes = txtLocalidade.Text,
                    IdLocalidade_Pes = Convert.ToInt32(txtIdLocalidade.Text),
                    Bairro_Pes = txtBairro.Text,
                    IdBairro_Pes = Convert.ToInt32(txtIdBairro.Text),
                    UF_Pes = txtUF.Text,
                    IdUf_Pes = Convert.ToInt32(txtIdUF.Text),

     

                };
               
                pessoaDAO.AtualizarPessoa(atualizar);

            }

     

    Vamos ao problema... SIMPLISMENTE NÃO FUNCIONA.... não atualiza os dados.


    Wenderson Sampaio
    domingo, 24 de julho de 2011 21:01

Respostas

  • Estou vendo que você já passa o id da pessoa, então você deve dar um attach do contexto nessa classe que você passa. Se não tiver o id, depois de fazer a consulta por outros parâmetros você deve passar os dados da classe alterada para outra que foi consultada antes do submitchanges. Abaixo segue exemplos:

    http://www.richardbushnell.net/2008/02/18/how-to-update-data-with-linq-to-sql/

    http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx

    http://www.techdreams.org/microsoft/aspnet/how-to-update-data-using-linq-to-sql-c-aspnet-programming/309-20080912


    Bruno Ferreira de Souza
    MSP - Microsoft Student Partner
    MCTS .NET Framework - Windows Applications
    MCPD .NET Framework - Windows Applications
    www.maestrodotnet.com.br
    @BrunoMaestro
    segunda-feira, 25 de julho de 2011 01:46
  • Olá Wenderson,

    Para atualizar um registro utilizando Linq vc deve atualizar a referência vinda do banco de dados...No caso vc apenas seleciona o registro, e não atribui nenhuma modificação... vc deve fazer o seguinte:

     

    public void AtualizarPessoa(TbPessoas objPessoa)
    {
    TbPessoas atualizar = dc.TbPessoas.Where(
    p => p.IdPessoa == objPessoa.IdPessoa).First();
    atualizar.campo1 = objPessoa.campo1;
    atualizar.campo2 = objPessoa.campo2;
    atualizar.campo3 = objPessoa.campo3;
    atualizar.campo4 = "outra modificação";
    
    dc.SubmitChanges();
    }
    
    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    terça-feira, 26 de julho de 2011 16:44
    Moderador
  • Eu prefiro fazer assim, Exemplo:

    public static Pessoa Atualizar(Pessoa p)
        {
          Tables.Context.DataClasses1DataContext ctx = new Tables.Context.DataClasses1DataContext();
          try
          {
            Pessoa pessoaT = ctx.Pessoas.Where(o => o.CpfCnpj.Equals(p.CpfCnpj)).Single();
            pessoaT.Nome = p.Nome;
            pessoaT.CpfCnpj = p.CpfCnpj;
            pessoaT.DataCriacao = p.DataCriacao;
            pessoaT.DataUltimaModificacao = DateTime.Now;
            pessoaT.Id = p.Id;
    
            ctx.SubmitChanges();
            return p;
          }
          catch (Exception e)
          {
            throw e;
          }
        }
    


    quarta-feira, 27 de julho de 2011 13:52
  • Olá Wenderson,

    Infelizmente o que vc deseja fazer não irá funcionar.

    Digo isso por o LINQ, para fazer Updates, trabalha com o conceito de instâncias de tuplas.

    Para atualizar uma linha, antes é preciso resgatar uma instância da tupla, para que ele saiba qual linha está sendo atualizada.

    A sua abordagem inicial de apenas passar a instância do objeto por parâmetro e  chamar o 'SubmitChanges' não irá funcionar, pois o LINQ não sabe qual instância atualizar.

    Mesmo que vc faça uma query no início do método não irá funcionar, pois vc apenas está resgatando a instância da tupla e não lhe esta atribuindo nenhum novo valor.

    De qualquer maneira, para atualizar o registro na base, é preciso fazer a atualização de valores dos atributos.

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    quinta-feira, 28 de julho de 2011 12:24
    Moderador

Todas as Respostas

  • Estou vendo que você já passa o id da pessoa, então você deve dar um attach do contexto nessa classe que você passa. Se não tiver o id, depois de fazer a consulta por outros parâmetros você deve passar os dados da classe alterada para outra que foi consultada antes do submitchanges. Abaixo segue exemplos:

    http://www.richardbushnell.net/2008/02/18/how-to-update-data-with-linq-to-sql/

    http://weblogs.asp.net/scottgu/archive/2007/05/19/using-linq-to-sql-part-1.aspx

    http://www.techdreams.org/microsoft/aspnet/how-to-update-data-using-linq-to-sql-c-aspnet-programming/309-20080912


    Bruno Ferreira de Souza
    MSP - Microsoft Student Partner
    MCTS .NET Framework - Windows Applications
    MCPD .NET Framework - Windows Applications
    www.maestrodotnet.com.br
    @BrunoMaestro
    segunda-feira, 25 de julho de 2011 01:46
  • Olá Bruno,

    gostei dos link com exemplo que você me mandou mas, mesmo fazendo um attach não funciona.

    Valeu pela tentativa...


    Wenderson Sampaio
    segunda-feira, 25 de julho de 2011 22:19
  • Olá Wenderson,

    Para atualizar um registro utilizando Linq vc deve atualizar a referência vinda do banco de dados...No caso vc apenas seleciona o registro, e não atribui nenhuma modificação... vc deve fazer o seguinte:

     

    public void AtualizarPessoa(TbPessoas objPessoa)
    {
    TbPessoas atualizar = dc.TbPessoas.Where(
    p => p.IdPessoa == objPessoa.IdPessoa).First();
    atualizar.campo1 = objPessoa.campo1;
    atualizar.campo2 = objPessoa.campo2;
    atualizar.campo3 = objPessoa.campo3;
    atualizar.campo4 = "outra modificação";
    
    dc.SubmitChanges();
    }
    
    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    terça-feira, 26 de julho de 2011 16:44
    Moderador
  • Olá Fernando,

     

    Dessa forma eu já havia feito para fazer um teste e funciona... mas eu teria que abrir mão da camada de acesso a dados DAO e assim para mim não serve... e se você observar no post, eu monto todo o objeto (atualizar) e depois para como parâmetro para a função da camada DAO. Eu já li alguns posts relacionados e faço exatamente como indicado mas não funciona...

     

    Valeu pela tentativa,

    Wenderson Sampaio


    Wenderson Sampaio
    terça-feira, 26 de julho de 2011 19:47
  • Oá Wenderson,

    Não acredito que vc terá de abrir mão de nenhuma de suas camadas.

    Não vejo como atualizar o item, sem q a instância do registro na base de dados seja consultada e atualizada

    Pode indicar na literatura onde encontrou essa recomendação de uso do do LINQ para updates?

     

    Obrigado

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    terça-feira, 26 de julho de 2011 19:56
    Moderador
  • Nesse código seu tenta fazer assim:

       dc.TbPessoas.Attach(objPessoa)
       dc.Refresh(Data.Linq.RefreshMode.KeepCurrentValues, objPessoa)
       dc.SubmitChanges()
    


     


    Bruno Ferreira de Souza
    MSP - Microsoft Student Partner
    MCTS .NET Framework - Windows Applications
    MCPD .NET Framework - Windows Applications
    www.maestrodotnet.com.br
    @BrunoMaestro
    terça-feira, 26 de julho de 2011 21:55
  • Eu prefiro fazer assim, Exemplo:

    public static Pessoa Atualizar(Pessoa p)
        {
          Tables.Context.DataClasses1DataContext ctx = new Tables.Context.DataClasses1DataContext();
          try
          {
            Pessoa pessoaT = ctx.Pessoas.Where(o => o.CpfCnpj.Equals(p.CpfCnpj)).Single();
            pessoaT.Nome = p.Nome;
            pessoaT.CpfCnpj = p.CpfCnpj;
            pessoaT.DataCriacao = p.DataCriacao;
            pessoaT.DataUltimaModificacao = DateTime.Now;
            pessoaT.Id = p.Id;
    
            ctx.SubmitChanges();
            return p;
          }
          catch (Exception e)
          {
            throw e;
          }
        }
    


    quarta-feira, 27 de julho de 2011 13:52
  • Oi Joabe,

    Assim eu já havia feito e funciona perfeitamente mas, eu utilizo as classes da camada DAO para gerenciar os métodos CRUD e eu quero utilizar essas classes para manter o objetivo das camadas.

     

    Valeu pela ajuda,

     


    Wenderson Sampaio
    quinta-feira, 28 de julho de 2011 01:28
  • Olá Wenderson,

    Infelizmente o que vc deseja fazer não irá funcionar.

    Digo isso por o LINQ, para fazer Updates, trabalha com o conceito de instâncias de tuplas.

    Para atualizar uma linha, antes é preciso resgatar uma instância da tupla, para que ele saiba qual linha está sendo atualizada.

    A sua abordagem inicial de apenas passar a instância do objeto por parâmetro e  chamar o 'SubmitChanges' não irá funcionar, pois o LINQ não sabe qual instância atualizar.

    Mesmo que vc faça uma query no início do método não irá funcionar, pois vc apenas está resgatando a instância da tupla e não lhe esta atribuindo nenhum novo valor.

    De qualquer maneira, para atualizar o registro na base, é preciso fazer a atualização de valores dos atributos.

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    quinta-feira, 28 de julho de 2011 12:24
    Moderador
  • Wenderson,

    Pesquisei e achei o seguinte :)

     

    public void AtualizarPessoa(TbPessoas objPessoa)
    {
    dc.TbPessoas.Attach(objPessoa);
    dc.SubmitChanges();
    }
    


    Nunca trabalhei com opção de dados desconectados do LINQ, mas acredito que isso resolva seu problema =]

    []s!


    Fernando Henrique Inocêncio Borba Ferreira
    while(alive){ this.WriteCode(); }
    Blog: http://ferhenriquef.wordpress.com/
    Twitter: @ferhenrique
    quinta-feira, 28 de julho de 2011 13:17
    Moderador