VB 2005 - Atualizando dados com TableAdapter


Como atualizar os dados usando o TableAdapter ?

Após você realizar as alterações no seu DataSet você deve enviar os dados para o banco de dados. Lembre-se que um DataSet trabalha no modo desconectado e se você não enviar as atualizações para o banco de dados ele não refletirá as operações feitas no DataSet.

Se estiver usando um TableAdapter você deve usar o comando Update deste componente para atualizar as tabelas correspondentes no banco de dados.

Os TableAdapters usam comandos de dados para ler e para escrever em uma fonte de dados. O método Fill associado a consulta é a base para criar o esquema da tabela de dados associada com como os comandos insertCommand, UpdateCommand, e DeleteCommand associados com o método Update do TableAdapter.

Desta forma ao chamar o método Update ele executa a instrução criada quando o TableAdapter foi originalmente configurado e não uma das consultas adicionais que podem ter sido criadas com o Assistente de configuração do TableAdapter.

O componente TableAdapter ira executar os comandos : INSERT, UPDATE E DELETE tendo como base os valores obtidos para a propriedade RowState.

A propriedade RowState obtém um dos valores da enumeração DataRowState da classe DataRow. Os valores possíveis para esta enumeração são:

Nome do membro Descrição
Added A linha foi adicionada ao DataRowCollection e o método AcceptChanges não foi chamado.
Deleted A linha foi excluída usando o método Delete da DataRow
Detached A linha foi criada mas não faz parte de qualquer DataRowCollection. A DataRow está nesse estado imediatamente após ele ter sido criada e para que ela seja adicionada a uma coleção, ou se ele tiver sido removida de uma coleção. 
Modified A linha tenha sido modificada e o método AcceptChanges não foi chamado. 
Unchanged A linha não foi alterada desde que o método AcceptChanges foi chamado pela última vez.

Estes valores dependem de dois fatores:

  1. Do tipo de operação que foi realizada na linha;
  2. Se o método AcceptChanges tiver sido chamado no DataRow;
Ao invocar o método AcceptChanges para um DataRow, o método EndEdit é implicitamente chamado para encerrar qualquer edição realizada. Se o valor da propriedade RowState de uma linha for igual a Added ou Modified, o valor da propriedade RowState torna-se igual a Unchanged. Se o valor de RowState for igual a Deleted a linha é removida.

A classe Datatable também possui um método AcceptChanges o qual afeta as alterações feitas para a toda a tabela.

O procedimento exato para atualizar uma fonte de dados pode variar dependendo das necessidades do seu negócio mas sua aplicação deverá realizar os seguintes passos:

  1. Chamar o método Update do adaptador dentro de um bloco Try/Catch;
  2. Se uma exceção for capturada, localize a linha de dados que causou o erro;
  3. Corrija o erro na linha de dados e tente atualizar novamente;
Para localizar linhas que possuem erros em seu DataSet faça o seguinte:
  • Verifique a propriedade HasErrors e veja se existe qualquer erro no seu dataset;
  • Se a propriedade HasErrors for igual a true, então percorra a coleção de tabelas e a seguir de
    linhas para encontrar a linha com erro:
Private Sub encontraErros()
Dim table As Data.DataTable
Dim row As Data.DataRow

If DataSet1.HasErrors Then
              For Each table In DataSet1.Tables
                          If table.HasErrors Then
                                     For Each row In table.Rows
                                             If row.HasErrors Then
                                                          ' Processar o erro  
                                             End If
                                       Next
                            End If
                Next
End If
End Sub

Para salvar os dados para o banco de dados chame o método Update do TableAdapter passando o nome da tabela que contém os valores que deverão ser escritos no banco de dados.

O trecho de código que pode ser usado para realizar tal operação:

Try
   Me.Validate()
   Me.CustomersBindingSource.EndEdit()
   Me.CustomersTableAdapter.Update(Me.NorthwindDataSet.Customers)
   MsgBox("Atualização realizada com sucesso...")
Catch ex As Exception
   MsgBox("A atualização falhou...")
End Try

- EndEdit - aplica as alterações pendentes a fonte de dados
- Update(NortwhindDataSet.Customers) - envia as alterações para o banco de dados, informando o dataset e a tabela a ser atualizada;(Existem outros métodos Updates sobrecarregados onde a assinatura é diferente e com isso os parâmetros informados podem variar)

Atualizando tabelas relacionadas

Quando você precisar atualizar tabelas relacionadas em um dataset é importante atualizar as tabelas na sequência correta a fim de reduzir a chance de gerar um erro relacionado integridade referencial.

A ordem de execução do comando também seguira os índices da coleção DataRowCollection no dataset. Para evitar erros relacionados a integridade dos dados ocorram a melhor maneira é atualizar o banco de dados usando a seguinte sequência:

  1. Tabela filha - deletar os registros;
  2. Tabela Pai - inserir , atualizar e deletar registros;
  3. Tabela Filha - inserir e atualizar registros;
Um DatarowCollection é o componente principal de um objeto DataTable; enquanto que DataColumnCollection define o esquema da tabela , DataRowCollection contém os dados atuais da tabela, onde cada DataRow que compõe um DataRowCollection representa uma linha única (registro).

Se você esta atualizando duas ou mais tabelas relacionadas deverá incluir toda a lógica de atualização em uma transação. Uma transação é um processo que assegura que todas as mudanças relacionadas feitas no banco de dados tenham sido completadas com sucesso antes de confirmar, através do comando commit, qualquer mudança.

Transações são grupos de operações combinadas em uma unidade lógica de trabalho. Elas são usadas para controlar e manter a consistência e integridade de cada ação na transação, a despeito dos erros que possam ocorrer no sistema.

Para saber mais sobre transações veja o artigo :

A seguir temos um exemplo de realização de tal operação. As etapas a serem cumpridas são :

  1. Crie três tabelas temporárias para tratar os registros diferentes;
  2. Chame o método Update para cada subconjunto de linhas usando um bloco try/catch. Se ocorrem erros, verifique e corrija;
  3. Confirme as alterações para o banco de dados (Commit);
  4. Libere os recursos alocados quando da criação das tabelas temporárias;

O exemplo abaixo trata com as tabelas Orders e Customers. Essas tabelas possui um relacionamento mostrado a seguir:

A tabela Customers é a tabela Pai e a tabela Orders a tabela filha;

- Criamos uma tabela para os registros deletados;
- Uma tabela para os novos registros;
- Uma tabela para os registros modificados;

 

Private Sub AtualizaBD()

'cria as tabelas para tratar os registros diferentes: deletados, novos e modificados

Dim deletedChildRecords As NorthwindDataSet.OrdersDataTable = _
CType(NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Deleted), NorthwindDataSet.OrdersDataTable)

Dim newChildRecords As NorthwindDataSet.OrdersDataTable = _
CType(NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Added), NorthwindDataSet.OrdersDataTable)

Dim modifiedChildRecords As NorthwindDataSet.OrdersDataTable = _
CType(NorthwindDataSet.Orders.GetChanges(Data.DataRowState.Modified), NorthwindDataSet.OrdersDataTable)

'Atualiza a tabela filha ->  Orders

Try
If deletedChildRecords IsNot Nothing Then
    OrdersTableAdapter.Update(deletedChildRecords)
End If

'atualiza a tabela Pai -> Customers
CustomersTableAdapter.Update(NorthwindDataSet.Customers)

If newChildRecords IsNot Nothing Then
    OrdersTableAdapter.Update(newChildRecords)
End If

If modifiedChildRecords IsNot Nothing Then
    OrdersTableAdapter.Update(modifiedChildRecords)
End If

'salva as alterações no banco de dados
NorthwindDataSet.AcceptChanges()

Catch ex As Exception
   MessageBox.Show("Ocorreu um erro durante o processo de atualização")
Finally
   'libera os recursos alocados
   If deletedChildRecords IsNot Nothing Then
        deletedChildRecords.Dispose()
  End If
  If newChildRecords IsNot Nothing Then
       newChildRecords.Dispose()
  End If
  If modifiedChildRecords IsNot Nothing Then
      modifiedChildRecords.Dispose()
  End If
End Try
End Sub

Com isso temos um panorama geral sobre como atualizar dados usando um TableAdapter.

Além das instruções InsertCommand, UpdateCommand, and DeleteCommand, o componente é criado com métodos que podem ser executados diretamente no banco de dados. Estes métodos podem ser chamados diretamente para manipular dados. Os métodos são: TableAdapter.Insert, TableAdapter.Update, e TableAdapter.Delete.

Se você não deseja criar estes métodos, defina a propriedade GenerateDbDirectMethods do TableAdapter como false.

Até o próximo artigo .NET ...

Veja outros artigos sobre TableAdapter aqui:

- VB  2005  - Camada de dados e TableAdapters em Windows Forms
-
ASP.NET 2.0 -  Criando uma camada de acesso a dados
- http://msdn2.microsoft.com/en-us/library/bz9tthwx(VS.80).aspx


José Carlos Macoratti