Compartilhar via


Validar dados em conjuntos de dados em aplicativos do .NET Framework

Observação

Os conjuntos de dados e as classes relacionadas são tecnologias herdadas do .NET Framework do início dos anos 2000 que permitem que os aplicativos trabalhem com dados na memória enquanto os aplicativos estão desconectados do banco de dados. As tecnologias são bastante úteis em aplicativos que permitem que os usuários modifiquem dados e persistam as alterações no banco de dados. Embora os conjuntos de dados tenham se mostrado uma tecnologia muito bem-sucedida, é recomendado que os novos aplicativos .NET usem o Entity Framework Core. O Entity Framework proporciona uma forma mais natural de trabalhar com dados tabulares como modelos de objeto e conta com uma interface de programação mais simples.

Validar dados é o processo de confirmar que os valores inseridos em objetos de dados estão em conformidade com as restrições dentro do esquema de um conjunto de dados. O processo de validação também confirma que esses valores estão seguindo as regras que foram estabelecidas para seu aplicativo. É uma boa prática validar dados antes de enviar atualizações para o banco de dados subjacente. Isso reduz os erros e o número potencial de viagens de ida e volta entre um aplicativo e o banco de dados.

Você pode confirmar se os dados que estão sendo gravados em um conjunto de dados são válidos criando verificações de validação no próprio conjunto de dados. O conjunto de dados pode verificar os dados independentemente de como a atualização está sendo executada, seja diretamente por controles em um formulário, dentro de um componente ou de alguma outra maneira. Como o conjunto de dados faz parte do aplicativo (ao contrário do back-end do banco de dados), é um local lógico para compilar a validação específica do aplicativo.

O melhor lugar para adicionar validação ao seu aplicativo é no arquivo de classe parcial do conjunto de dados. No Visual Basic ou Visual C#, abra o Designer de Conjunto de Dados e clique duas vezes na coluna ou tabela para a qual você deseja criar a validação. Essa ação abre o arquivo de código, no qual você pode criar um manipulador de eventos ColumnChanging ou RowChanging.

private static void OnColumnChanging(object sender, DataColumnChangeEventArgs e)
{

}

Validar os dados

A validação em um conjunto de dados é realizada das seguintes maneiras:

  • Criando sua validação específica do aplicativo que pode verificar valores em uma coluna de dados individual durante as alterações. Para obter mais informações, confira Como validar dados durante alterações de coluna.

  • Criando sua validação específica do aplicativo que pode verificar dados em valores enquanto uma linha de dados inteira está sendo alterada. Para obter mais informações, confira Como validar dados durante alterações de linha.

  • Criando chaves, restrições exclusivas e assim por diante como parte da definição de esquema real do conjunto de dados.

  • Definindo as propriedades do objeto DataColumn, como MaxLength, AllowDBNull e Unique.

Vários eventos são gerados pelo objeto DataTable quando uma alteração está ocorrendo em um registro:

  • Os eventos ColumnChanging e ColumnChanged são gerados durante e após cada alteração para uma coluna individual. O evento ColumnChanging é útil quando você deseja validar alterações em colunas específicas. Informações sobre a alteração proposta são passadas como um argumento com o evento.
  • Os eventos RowChanging e RowChanged são gerados durante e após qualquer alteração em uma linha. O evento RowChanging é mais geral. Indica que uma alteração está ocorrendo em algum lugar da linha, mas você não sabe qual coluna foi alterada.

Por padrão, cada alteração em uma coluna gera quatro eventos. O primeiro são os eventos ColumnChanging e ColumnChanged para a coluna específica que está sendo alterada. A seguir estão os eventos RowChanging e RowChanged. Se várias alterações estiverem sendo feitas na linha, os eventos serão gerados para cada alteração.

Observação

O método BeginEdit da linha de dados desativa os eventos RowChanging e RowChanged após cada alteração de coluna individual. Nesse caso, o evento não é gerado até que o método EndEdit tenha sido chamado, quando os eventos RowChanging e RowChanged são acionados apenas uma vez. Para obter mais informações, confira Desativar restrições ao preencher um conjunto de dados.

O evento escolhido depende de quão granular você deseja que a validação seja. Se for importante que você capture um erro imediatamente quando uma coluna for alterada, crie a validação usando o evento ColumnChanging. Caso contrário, use o evento RowChanging, que pode resultar na captura de vários erros ao mesmo tempo. Além disso, se os dados estiverem estruturados para que o valor de uma coluna seja validado com base no conteúdo de outra coluna, execute a validação durante o evento RowChanging.

Quando os registros são atualizados, o objeto DataTable gera eventos aos quais você pode responder à medida que as alterações estão ocorrendo e depois que as alterações são feitas.

Se o aplicativo usar um conjunto de dados tipados, você poderá criar manipuladores de eventos fortemente tipados. Isso adiciona quatro eventos tipados adicionais para os quais você pode criar manipuladores: dataTableNameRowChanging, dataTableNameRowChanged, dataTableNameRowDeleting e dataTableNameRowDeleted. Esses manipuladores de eventos tipados passam um argumento que inclui os nomes de coluna da tabela que facilitam a gravação e a leitura do código.

Eventos de atualização de dados

Evento Descrição
ColumnChanging O valor em uma coluna está sendo alterado. O evento passa a linha e a coluna para você, juntamente com o novo valor proposto.
ColumnChanged O valor em uma coluna foi alterado. O evento passa a linha e a coluna para você, juntamente com o valor proposto.
RowChanging As alterações feitas em um objeto DataRow estão prestes a ser confirmadas novamente no conjunto de dados. Se você não tiver chamado o método BeginEdit, o evento RowChanging será gerado para cada alteração em uma coluna imediatamente após o evento ColumnChanging ter sido gerado. Se você tiver chamado BeginEdit antes de fazer alterações, o evento RowChanging será gerado somente quando você chamar o método EndEdit.

O evento passa a linha para você, juntamente com um valor que indica que tipo de ação (alterar, inserir e assim por diante) está sendo executado.
RowChanged Uma linha foi alterada. O evento passa a linha para você, juntamente com um valor que indica que tipo de ação (alterar, inserir e assim por diante) está sendo executado.
RowDeleting Uma linha está sendo excluída. O evento passa a linha para você, juntamente com um valor que indica que tipo de ação (excluir) está sendo executado.
RowDeleted Uma linha foi excluída. O evento passa a linha para você, juntamente com um valor que indica que tipo de ação (excluir) está sendo executado.

Os eventos ColumnChanging, RowChanging e RowDeleting são gerados durante o processo de atualização. Você pode usar esses eventos para validar dados ou executar outros tipos de processamento. Como a atualização está em processo durante esses eventos, você pode cancelar lançando uma exceção, o que impede que a atualização seja concluída.

Os eventos ColumnChanged, RowChanged e RowDeleted são eventos de notificação gerados quando a atualização é concluída com êxito. Esses eventos são úteis quando você deseja executar outras ações com base em uma atualização bem-sucedida.

Validar dados durante alterações da coluna

Observação

O Designer de Conjunto de Dados cria uma classe parcial na qual a lógica de validação pode ser adicionada a um conjunto de dados. O conjunto de dados gerado pelo designer não exclui nem altera nenhum código na classe parcial.

Você pode validar dados quando o valor em uma coluna de dados for alterado respondendo ao evento ColumnChanging. Quando gerado, esse evento passa um argumento de evento (ProposedValue) que contém o valor que está sendo proposto para a coluna atual. Com base no conteúdo de e.ProposedValue, você poderá:

  • Aceitar o valor proposto sem fazer nada.

  • Rejeitar o valor proposto definindo o erro da coluna (SetColumnError) de dentro do manipulador de eventos de alteração da coluna.

  • Opcionalmente, usar um controle ErrorProvider para exibir uma mensagem de erro para o usuário. Para obter mais informações, confira Componente ErrorProvider.

A validação também pode ser executada durante o evento RowChanging.

Validar dados durante alterações de linha

Você pode escrever código para verificar se cada coluna que deseja validar contém dados que atendam aos requisitos do aplicativo. Faça isso definindo a coluna para indicar que ela contém um erro se um valor proposto for inaceitável. Os exemplos a seguir definem um erro de coluna quando a coluna Quantity é de 0 ou menos. Os manipuladores de eventos de alteração de linha devem ser semelhantes aos exemplos a seguir.

Para validar dados quando uma linha é alterada (Visual Basic)

  1. Abra o conjunto de dados no Designer de Conjunto de Dados. Para obter mais informações, confira Passo a passo: criar um conjunto de dados no Designer de Conjunto de Dados.

  2. Clique duas vezes na barra de título da tabela que você deseja validar. Essa ação cria automaticamente o manipulador de eventos RowChanging do DataTable no arquivo de classe parcial do conjunto de dados.

    Dica

    Clique duas vezes à esquerda do nome da tabela para criar o manipulador de eventos de alteração de linha. Se você clicar duas vezes no nome da tabela, poderá editá-lo.

    Private Sub Order_DetailsDataTable_Order_DetailsRowChanging(
        ByVal sender As System.Object, 
        ByVal e As Order_DetailsRowChangeEvent
      ) Handles Me.Order_DetailsRowChanging
    
        If CType(e.Row.Quantity, Short) <= 0 Then
            e.Row.SetColumnError("Quantity", "Quantity must be greater than 0")
        Else
            e.Row.SetColumnError("Quantity", "")
        End If
    End Sub
    

Para validar dados quando uma linha é alterada (C#)

  1. Abra o conjunto de dados no Designer de Conjunto de Dados. Para obter mais informações, confira Passo a passo: criar um conjunto de dados no Designer de Conjunto de Dados.

  2. Clique duas vezes na barra de título da tabela que você deseja validar. Essa ação cria um arquivo de classe parcial para o DataTable.

    Observação

    O Designer de Conjunto de Dados não cria automaticamente um manipulador de eventos para o evento RowChanging. Você precisa criar um método para manipular o evento RowChanging e executar o código para conectar o evento no método de inicialização da tabela.

  3. Copie o seguinte código na classe parcial:

    public override void EndInit()
    {
        base.EndInit();
        Order_DetailsRowChanging += TestRowChangeEvent;
    }
    
    public void TestRowChangeEvent(object sender, Order_DetailsRowChangeEvent e)
    {
        if ((short)e.Row.Quantity <= 0)
        {
            e.Row.SetColumnError("Quantity", "Quantity must be greater than 0");
        }
        else
        {
            e.Row.SetColumnError("Quantity", "");
        }
    }
    

Para recuperar linhas alteradas

Cada linha em uma tabela de dados tem uma propriedade RowState que mantém o controle do estado atual dessa linha usando os valores na enumeração DataRowState. Você pode retornar linhas alteradas de um conjunto de dados ou tabela de dados chamando o método GetChanges de um DataSet ou DataTable. Você pode verificar se há alterações antes de chamar GetChanges chamando o método HasChanges de um conjunto de dados.

Observação

Depois de confirmar alterações em um conjunto de dados ou tabela de dados (chamando o método AcceptChanges), o método GetChanges não retorna dados. Se o aplicativo precisar processar linhas alteradas, você deverá processar as alterações antes de chamar o método AcceptChanges.

Chamar o método GetChanges de um conjunto de dados ou tabela de dados retorna um novo conjunto de dados ou tabela de dados que contém apenas registros que foram alterados. Se você quiser obter registros específicos, por exemplo, apenas registros novos ou apenas registros modificados, poderá passar um valor da enumeração DataRowState como um parâmetro para o método GetChanges.

Use a enumeração DataRowVersion para acessar as diferentes versões de uma linha (por exemplo, os valores originais que estavam em uma linha antes de processá-la).

Para obter todos os registros alterados de um conjunto de dados

  • Chame o método GetChanges de um conjunto de dados.

    O exemplo a seguir cria um novo conjunto de dados chamado changedRecords e o preenche com todos os registros alterados de outro conjunto de dados chamado dataSet1.

    DataSet changedRecords = dataSet1.GetChanges();
    

Para obter todos os registros alterados de uma tabela de dados

  • Chame o método GetChanges de uma Tabela de Dados.

    O exemplo a seguir cria uma nova tabela de dados chamada changedRecordsTable e a preenche com todos os registros alterados de outra tabela de dados chamada dataTable1.

    DataTable changedRecordsTable = dataTable1.GetChanges();
    

Para obter todos os registros que têm um estado de linha específico

  • Chame o método GetChanges de um conjunto de dados ou tabela de dados e passe um valor de enumeração DataRowState como um argumento.

    O exemplo a seguir mostra como criar um novo conjunto de dados chamado addedRecords e preencher somente com registros que foram adicionados ao conjunto de dados dataSet1.

    DataSet addedRecords = dataSet1.GetChanges(DataRowState.Added);
    

    O seguinte exemplo mostra como retornar todos os registros que foram adicionados recentemente à tabela Customers:

    private NorthwindDataSet.CustomersDataTable GetNewRecords()
    {
        return (NorthwindDataSet.CustomersDataTable)
            northwindDataSet1.Customers.GetChanges(DataRowState.Added);
    }
    

Acessar a versão original de uma Linha de Dados

Quando são feitas alterações em linhas de dados, o conjunto de dados retém as versões original (Original) e nova (Current) da linha. Por exemplo, antes de chamar o método AcceptChanges, seu aplicativo pode acessar as diferentes versões de um registro (conforme definido na enumeração DataRowVersion) e processar as alterações adequadamente.

Observação

Versões diferentes de uma linha aparecerão somente depois que ela for editada e antes de o método AcceptChanges ser chamado. Depois que o método AcceptChanges tiver sido chamado, as versões atuais e originais serão as mesmas.

Passar o valor DataRowVersion junto com o índice de coluna (ou nome da coluna como uma cadeia de caracteres) retorna o valor da versão de linha específica dessa coluna. A coluna alterada é identificada durante os eventos ColumnChanging e ColumnChanged. Este é um bom momento para inspecionar as diferentes versões de linha para fins de validação. No entanto, se você suspendeu temporariamente as restrições, esses eventos não serão gerados e será necessário identificar programaticamente quais colunas foram alteradas. Você pode fazer isso iterando pela coleção Columns e comparando os diferentes valores DataRowVersion.

Para obter a versão original de um registro

  • Acesse o valor de uma coluna passando o DataRowVersion da linha que você deseja retornar.

    O seguinte exemplo mostra como usar um valor DataRowVersion para obter o valor original de um campo CompanyName em um DataRow:

    string originalCompanyName;
    originalCompanyName = northwindDataSet1.Customers[0]
        ["CompanyName", DataRowVersion.Original].ToString();
    

Acessar a versão atual de uma Linha de Dados

Para obter a versão atual de um registro

  • Acesse o valor de uma coluna e adicione um parâmetro ao índice que indica qual versão de uma linha você deseja retornar.

    O seguinte exemplo mostra como usar um valor DataRowVersion para obter o valor atual de um campo CompanyName em um DataRow:

    string currentCompanyName;
    currentCompanyName = northwindDataSet1.Customers[0]
        ["CompanyName", DataRowVersion.Current].ToString();