none
Ajuda com Update() EF6 RRS feed

  • Pergunta

  • Amigos, venho mais uma vez pedir ajuda de vocês. Estou com um problema para atualizar registros no DB via EF6. Tenho uma aplicação Windows Forms. Consulto e preencho um ListView com dados retornados do banco. No SelectedIndexChanged preencho alguns TextBox, até aí tudo bem. O problema é que quando eu altero alguma informação e tento atualizar no banco ele dá o erro: "Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=472540 for information on understanding and handling optimistic concurrency exceptions." Alguém pode me dizer como fazer Update com windows forms e EF6? Abaixo segue o código:

    Repositório Genérico:

    public void Update(TEntity entity)
    {
        context.Entry(entity).State = EntityState.Modified;            
    }

    Método Save onde, através de uma variável de teste eu defino se será realizado um Create() ou Update()

    CategoryRepository categoryRepository = new CategoryRepository();
    Category c = new Category();
    
    private void btnCategorySave_Click(object sender, EventArgs e)
    {
       try
       {
           if (IsValid())
           {
              if(entityId == 0)
              {   
                  c.Name = txbCategoryName.Text.Trim();
                  c.Description = txbCategoryDescription.Text.Trim();
    
                  categoryRepository.Create(c);
                  categoryRepository.Save();
                  MessageBox.Show("Registro gravado com sucesso.");
    
                  txbCategoryName.Clear();
                  txbCategoryDescription.Clear();
               }
               else
               {                         
                   c.Name = txbCategoryName.Text.Trim();
                   c.Description = txbCategoryDescription.Text.Trim();
    
                   categoryRepository.Update(c);
                   categoryRepository.Save();
                   MessageBox.Show("Registro atualizado com sucesso.");
    
                   txbCategoryName.Clear();
                   txbCategoryDescription.Clear();
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Um erro ocorreu durante o processo: " + ex.Message);
        }
    }
    Desde já agradeço.
    • Movido welington jr sábado, 18 de novembro de 2017 13:12 forum certo
    sábado, 18 de novembro de 2017 01:11

Respostas

  • Olá Uitan,

    Esse problema é decorrido pela seguinte razão, você não passou qual é o registro que será atualizado!

    private void btnCategorySave_Click(object sender, EventArgs e)
    {
       try
       {
           if (IsValid())
           {
              if(entityId == 0) // Onde você encontra esse Valor?
              {   
                  c.Name = txbCategoryName.Text.Trim();
                  c.Description = txbCategoryDescription.Text.Trim();
    
                  categoryRepository.Create(c);
                  categoryRepository.Save();
                  MessageBox.Show("Registro gravado com sucesso.");
    
                  txbCategoryName.Clear();
                  txbCategoryDescription.Clear();
               }
               else
               {  
                   //Tente encontrar o registro assim
                   c =  categoryRepository.Category.FirstOrDefault(x => x.Id == entityId);
                   c.Name = txbCategoryName.Text.Trim();
                   c.Description = txbCategoryDescription.Text.Trim();
    
                   categoryRepository.Update(c);
                   categoryRepository.Save();
                   MessageBox.Show("Registro atualizado com sucesso.");
    
                   txbCategoryName.Clear();
                   txbCategoryDescription.Clear();
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Um erro ocorreu durante o processo: " + ex.Message);
        }
    }

    O problema acontece por que você está tentando atualizar um registro sem passar o valor da chave primária, a qual o EF mapea para controlar a interação com o banco.

    Acredito também que se fizer assim, deverá funcionar:

    private void btnCategorySave_Click(object sender, EventArgs e)
    {
       try
       {
           if (IsValid())
           {
              if(entityId == 0)
              {   
                  c.Name = txbCategoryName.Text.Trim();
                  c.Description = txbCategoryDescription.Text.Trim();
    
                  categoryRepository.Create(c);
                  categoryRepository.Save();
                  MessageBox.Show("Registro gravado com sucesso.");
    
                  txbCategoryName.Clear();
                  txbCategoryDescription.Clear();
               }
               else
               {  
                   //O campo Id suponho que seja sua primary key!
                   c.Id = entityId;
                   c.Name = txbCategoryName.Text.Trim();
                   c.Description = txbCategoryDescription.Text.Trim();
    
                   categoryRepository.Update(c);
                   categoryRepository.Save();
                   MessageBox.Show("Registro atualizado com sucesso.");
    
                   txbCategoryName.Clear();
                   txbCategoryDescription.Clear();
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Um erro ocorreu durante o processo: " + ex.Message);
        }
    }

    Rafael Almeida
    Senior Developer .NET C#
    Development Leader at JAMSOFT Informática
    Criador e Mantenedor do Entity Framework Core for Firebird
    Contribuidor do Entity Framework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    • Sugerido como Resposta Antero Marques sábado, 18 de novembro de 2017 03:36
    • Marcado como Resposta UitanMaciel_ sábado, 18 de novembro de 2017 10:13
    sábado, 18 de novembro de 2017 02:37
  • Obrigado Rafael, sua reposta ajudou bastante. O problema foi resolvido como descreveu acima:

    c =  categoryRepository.Category.FirstOrDefault(x => x.Id == entityId);

    Se seu problema foi resolvido marque como útil/resposta!

    Rafael Almeida
    Senior Developer .NET C#
    Development Leader at JAMSOFT Informática
    Criador e Mantenedor do Entity Framework Core for Firebird
    Contribuidor do Entity Framework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    • Marcado como Resposta UitanMaciel_ sábado, 18 de novembro de 2017 10:13
    sábado, 18 de novembro de 2017 02:59

Todas as Respostas

  • Olá Uitan,

    Esse problema é decorrido pela seguinte razão, você não passou qual é o registro que será atualizado!

    private void btnCategorySave_Click(object sender, EventArgs e)
    {
       try
       {
           if (IsValid())
           {
              if(entityId == 0) // Onde você encontra esse Valor?
              {   
                  c.Name = txbCategoryName.Text.Trim();
                  c.Description = txbCategoryDescription.Text.Trim();
    
                  categoryRepository.Create(c);
                  categoryRepository.Save();
                  MessageBox.Show("Registro gravado com sucesso.");
    
                  txbCategoryName.Clear();
                  txbCategoryDescription.Clear();
               }
               else
               {  
                   //Tente encontrar o registro assim
                   c =  categoryRepository.Category.FirstOrDefault(x => x.Id == entityId);
                   c.Name = txbCategoryName.Text.Trim();
                   c.Description = txbCategoryDescription.Text.Trim();
    
                   categoryRepository.Update(c);
                   categoryRepository.Save();
                   MessageBox.Show("Registro atualizado com sucesso.");
    
                   txbCategoryName.Clear();
                   txbCategoryDescription.Clear();
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Um erro ocorreu durante o processo: " + ex.Message);
        }
    }

    O problema acontece por que você está tentando atualizar um registro sem passar o valor da chave primária, a qual o EF mapea para controlar a interação com o banco.

    Acredito também que se fizer assim, deverá funcionar:

    private void btnCategorySave_Click(object sender, EventArgs e)
    {
       try
       {
           if (IsValid())
           {
              if(entityId == 0)
              {   
                  c.Name = txbCategoryName.Text.Trim();
                  c.Description = txbCategoryDescription.Text.Trim();
    
                  categoryRepository.Create(c);
                  categoryRepository.Save();
                  MessageBox.Show("Registro gravado com sucesso.");
    
                  txbCategoryName.Clear();
                  txbCategoryDescription.Clear();
               }
               else
               {  
                   //O campo Id suponho que seja sua primary key!
                   c.Id = entityId;
                   c.Name = txbCategoryName.Text.Trim();
                   c.Description = txbCategoryDescription.Text.Trim();
    
                   categoryRepository.Update(c);
                   categoryRepository.Save();
                   MessageBox.Show("Registro atualizado com sucesso.");
    
                   txbCategoryName.Clear();
                   txbCategoryDescription.Clear();
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Um erro ocorreu durante o processo: " + ex.Message);
        }
    }

    Rafael Almeida
    Senior Developer .NET C#
    Development Leader at JAMSOFT Informática
    Criador e Mantenedor do Entity Framework Core for Firebird
    Contribuidor do Entity Framework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    • Sugerido como Resposta Antero Marques sábado, 18 de novembro de 2017 03:36
    • Marcado como Resposta UitanMaciel_ sábado, 18 de novembro de 2017 10:13
    sábado, 18 de novembro de 2017 02:37
  • Obrigado Rafael pela resposta, mas já havia tentado fazer isso. Aí tenho como erro: Message = "Attaching an entity of type 'MedicalPlataform.Domain.Modules.General.Entities.Category' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity ...

    Tentei modificar meu método Update() para:

    public void Update(TEntity entity)
    {
       context.Entry(entity).State = EntityState.Modified;
       context.Set<TEntity>().Attach(entity);
    }
    Obtenho o mesmo erro.

    sábado, 18 de novembro de 2017 02:48
  • Obrigado Rafael, sua reposta ajudou bastante. O problema foi resolvido como descreveu acima:

    c =  categoryRepository.Category.FirstOrDefault(x => x.Id == entityId);

    sábado, 18 de novembro de 2017 02:54
  • Obrigado Rafael, sua reposta ajudou bastante. O problema foi resolvido como descreveu acima:

    c =  categoryRepository.Category.FirstOrDefault(x => x.Id == entityId);

    Se seu problema foi resolvido marque como útil/resposta!

    Rafael Almeida
    Senior Developer .NET C#
    Development Leader at JAMSOFT Informática
    Criador e Mantenedor do Entity Framework Core for Firebird
    Contribuidor do Entity Framework Core
    Email: ralms@ralms.net
    Blog -  GitHub  -  LinkedIn -  Twitter

    • Marcado como Resposta UitanMaciel_ sábado, 18 de novembro de 2017 10:13
    sábado, 18 de novembro de 2017 02:59