Validar datos en conjuntos de datos en aplicaciones .NET Framework

Nota:

Los conjuntos de datos y las clases relacionadas son tecnologías heredadas de .NET Framework de principios de la década de 2000 que permiten a las aplicaciones trabajar con datos en memoria mientras están desconectadas de la base de datos. Las tecnologías son especialmente útiles para las aplicaciones que permiten a los usuarios modificar los datos y conservar los cambios en la base de datos. Aunque los conjuntos de datos han demostrado ser una tecnología de gran éxito, se recomienda que las nuevas aplicaciones de .NET usen Entity Framework Core. Entity Framework proporciona una manera más natural de trabajar con datos tabulares como modelos de objetos y tiene una interfaz de programación más sencilla.

La validación de datos es el proceso de confirmar que los valores especificados en objetos de datos cumplen las restricciones dentro del esquema de un conjunto de datos. El proceso de validación también confirma que estos valores siguen las reglas establecidas para la aplicación. Se recomienda validar los datos antes de enviar actualizaciones a la base de datos subyacente. Esto reduce el número de errores así como el posible número de recorridos de ida y vuelta entre una aplicación y la base de datos.

Puede confirmar que los datos que se escriben en un conjunto de datos son válidos mediante la creación de comprobaciones de validación en el propio conjunto de datos. El conjunto de datos puede comprobar los datos independientemente de cómo se realice la actualización, ya sea directamente por controles de un formulario, dentro de un componente o de alguna otra manera. Dado que el conjunto de datos forma parte de la aplicación (a diferencia del back-end de la base de datos), es un lugar lógico para compilar la validación específica de la aplicación.

El mejor lugar para agregar validación a la aplicación es en el archivo de clase parcial del conjunto de datos. En Visual Basic o Visual C#, abra el Diseñador de DataSet y haga doble clic en la columna o tabla para la que desea crear la validación. Esta acción abre el archivo de código, donde puede crear un controlador de eventos ColumnChanging o RowChanging.

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

}

Validación de datos

La validación dentro de un conjunto de datos se realiza de las siguientes maneras:

El objeto DataTable genera varios eventos cuando se produce un cambio en un registro:

  • Los eventos ColumnChanging y ColumnChanged se generan durante y después de cada cambio en una columna individual. El evento ColumnChanging es útil cuando desea validar los cambios en columnas específicas. La información sobre el cambio propuesto se pasa como argumento con el evento.
  • Los eventos RowChanging y RowChanged se generan durante y después de cualquier cambio en una fila. El evento RowChanging es más general. Indica que se está produciendo un cambio en algún lugar de la fila, pero no sabe qué columna ha cambiado.

De forma predeterminada, cada cambio en una columna genera cuatro eventos. El primero son los eventos ColumnChanging y ColumnChanged de la columna específica que se va a cambiar. A continuación se muestran los eventos RowChanging y RowChanged. Si se realizan varios cambios en la fila, los eventos se generarán para cada cambio.

Nota

El método de datos BeginEdit de la fila desactiva los eventos RowChanging y RowChanged después de cada cambio de columna individual. En ese caso, el evento no se genera hasta que se ha llamado al método EndEdit, cuando los eventos RowChanging y RowChanged se generan una sola vez. Para más información, consulte Desactivación de restricciones al llenar un conjunto de datos.

El evento que elija dependerá de la granularidad que desee que sea la validación. Si es importante que detecte un error inmediatamente cuando cambia una columna, compile la validación mediante el evento ColumnChanging. De lo contrario, use el evento RowChanging, lo que podría dar lugar a la detección de varios errores a la vez. Además, si los datos están estructurados para que el valor de una columna se valide en función del contenido de otra columna, realice la validación durante el evento RowChanging.

Cuando se actualizan los registros, el objeto DataTable genera eventos a los que puede responder a medida que se producen cambios y después de realizar los cambios.

Si la aplicación usa un conjunto de datos con tipo, puede crear controladores de eventos fuertemente tipados. Esto agrega cuatro eventos con tipo adicionales para los que puede crear controladores: dataTableNameRowChanging, dataTableNameRowChanged, dataTableNameRowDeleting y dataTableNameRowDeleted. Estos controladores de eventos con tipo pasan un argumento que incluye los nombres de columna de la tabla que facilitan la escritura y lectura del código.

Eventos de actualización de datos

Evento Descripción
ColumnChanging Se está cambiando el valor de una columna. El evento le pasa la fila y la columna, junto con el nuevo valor propuesto.
ColumnChanged Se ha cambiado el valor de una columna. El evento le pasa la fila y la columna, junto con el valor propuesto.
RowChanging Los cambios realizados en un objeto DataRow están a punto de confirmarse en el conjunto de datos. Si no ha llamado al método BeginEdit, el evento RowChanging se genera para cada cambio en una columna inmediatamente después de que se haya generado el evento ColumnChanging. Si llamó a BeginEdit antes de realizar cambios, el evento RowChanging solo se genera cuando se llama al método EndEdit.

El evento pasa la fila al usuario, junto con un valor que indica qué tipo de acción (cambiar, insertar, etc.) se está realizando.
RowChanged Se ha cambiado una fila. El evento pasa la fila al usuario, junto con un valor que indica qué tipo de acción (cambiar, insertar, etc.) se está realizando.
RowDeleting Se está eliminando una fila. El evento pasa la fila al usuario, junto con un valor que indica qué tipo de acción (eliminar) se está realizando.
RowDeleted La fila se ha eliminado. El evento pasa la fila al usuario, junto con un valor que indica qué tipo de acción (eliminar) se está realizando.

Los eventos ColumnChanging, RowChanging y RowDeleting se generan durante el proceso de actualización. Puede usar estos eventos para validar los datos o realizar otros tipos de procesamiento. Dado que la actualización está en proceso durante estos eventos, puede cancelarla iniciando una excepción, lo que impide que finalice la actualización.

Los eventos ColumnChanged, RowChanged y RowDeleted son eventos de notificación que se generan cuando la actualización ha finalizado correctamente. Estos eventos son útiles cuando desea realizar más acciones en función de una actualización correcta.

Validación de datos durante los cambios de columna

Nota

El Diseñador de DataSet crea una clase parcial en la que la lógica de validación se puede agregar a un conjunto de datos. El conjunto de datos generado por el diseñador no elimina ni cambia ningún código de la clase parcial.

Puede validar los datos cuando se modifican los valores en una fila de datos respondiendo al evento ColumnChanging. Cuando se provoca, este evento pasa un argumento de evento (ProposedValue) que contiene el valor propuesto para la columna actual. En función del contenido de e.ProposedValue, puede:

  • Aceptar el valor propuesto sin hacer nada.

  • Rechazar el valor propuesto estableciendo el error de la columna (SetColumnError) desde el controlador de eventos que ha modificado la fila.

  • Utilizar opcionalmente un control ErrorProvider para mostrar un mensaje de error al usuario. Para obtener más información, vea ErrorProvider (Componente).

La validación también se puede realizar durante el evento RowChanging.

Validación de datos durante los cambios de fila

Puede escribir código para comprobar que cada columna que desee validar contiene datos que cumplen los requisitos de la aplicación. Para ello, establezca la columna para indicar que contiene un error si un valor propuesto no es aceptable. Los ejemplos siguientes establecen un error de la columna cuando la columna Quantity es igual o menor que 0. Los controladores de eventos que modifican la fila se parecerán a los ejemplos siguientes.

Para validar los datos cuando se modifica una fila (Visual Basic)

  1. Abra su conjunto de datos en el Diseñador de Dataset. Para más información, consulte Tutorial: Creación de un conjunto de datos en el Diseñador de DataSet.

  2. Haga doble clic en la barra de título de la tabla que desee validar. Esta acción crea automáticamente el controlador de eventos RowChanging del control DataTable en el archivo de clase parcial del conjunto de datos.

    Sugerencia

    Haga doble clic a la izquierda del nombre de la tabla para crear el controlador de eventos que modifique la fila. Si hace doble clic en el nombre de tabla, puede editarlo.

    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 los datos cuando se modifica una fila (C#)

  1. Abra su conjunto de datos en el Diseñador de Dataset. Para más información, consulte Tutorial: Creación de un conjunto de datos en el Diseñador de DataSet.

  2. Haga doble clic en la barra de título de la tabla que desee validar. Esta acción crea un archivo de clase parcial para el control DataTable.

    Nota:

    El Diseñador de DataSet no crea automáticamente un controlador de eventos para el evento RowChanging. Debe crear un método para controlar el evento RowChanging y ejecutar el código para enlazar el evento en el método de inicialización de la tabla.

  3. Copie el código siguiente en la clase 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 filas modificadas

Cada fila de una tabla de datos tiene una propiedad RowState que realiza un seguimiento del estado actual de esa fila mediante los valores de la enumeración DataRowState. Puede devolver filas modificadas de un conjunto de datos o una tabla de datos llamando al método GetChanges de DataSet o DataTable. Puede comprobar que existen cambios antes de llamar a GetChanges mediante una llamada al método HasChanges de un conjunto de datos.

Nota:

Después de confirmar los cambios en un conjunto de datos o una tabla de datos (llamando al método AcceptChanges), el método GetChanges no devuelve datos. Si la aplicación necesita procesar filas modificadas, debe procesar los cambios antes de llamar al método AcceptChanges.

Al llamar al método GetChanges de un conjunto de datos o una tabla de datos, se devuelve un nuevo conjunto de datos o tabla de datos que contiene solo los registros que se han cambiado. Si desea obtener registros específicos (por ejemplo, solo registros nuevos o solo registros modificados), puede pasar un valor de la enumeración DataRowState como parámetro al método GetChanges.

Use la enumeración DataRowVersion para acceder a las distintas versiones de una fila (por ejemplo, los valores originales que estaban en una fila antes de procesarla).

Para obtener todos los registros modificados de un conjunto de datos

  • Llame al método GetChanges de un conjunto de datos.

    En el ejemplo siguiente se crea un nuevo conjunto de datos denominado changedRecords y se rellena con todos los registros modificados de otro conjunto de datos denominado dataSet1.

    DataSet changedRecords = dataSet1.GetChanges();
    

Para obtener todos los registros modificados de una tabla de datos

  • Llame al método GetChanges de una DataTable.

    En el ejemplo siguiente se crea una nueva tabla de datos denominada changedRecordsTable y se rellena con todos los registros modificados de otra tabla de datos denominada dataTable1.

    DataTable changedRecordsTable = dataTable1.GetChanges();
    

Para obtener todos los registros que tienen un estado de fila específico

  • Llame al método GetChanges de un conjunto de datos o tabla de datos y pase un valor de enumeración DataRowState como argumento.

    En el ejemplo siguiente se muestra cómo crear un nuevo conjunto de datos denominado addedRecords y rellenarlo solo con registros que se han agregado al conjunto de datos dataSet1.

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

    En el ejemplo siguiente se muestra cómo devolver todos los registros que se agregaron recientemente a la tabla Customers:

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

Acceso a la versión original de un DataRow

Cuando los cambios se realizan en las filas de datos, el conjunto de datos retiene tanto la versión original (Original) como las versiones nuevas (Current) de la fila. Por ejemplo, antes de llamar al método AcceptChanges, su aplicación puede tener acceso a las distintas versiones de un registro (según se defina en la enumeración DataRowVersion) y procesar los cambios según corresponda.

Nota:

Las versiones diferentes de una fila sólo existen después de que ésta haya sido revisada y antes de haber llamado al método AcceptChanges. Una vez que se ha llamado al método AcceptChanges, las versiones actual y original son iguales.

Si se pasa el valor DataRowVersion junto con el índice de la columna (o el nombre de la columna como cadena), se devuelve el valor de la versión de fila concreta de esa columna. La columna modificada se identifica durante los eventos ColumnChanging y ColumnChanged. Este es un buen momento para inspeccionar las diferentes versiones de fila con fines de validación. Sin embargo, si ha suspendido las restricciones temporalmente, esos eventos no se provocarán y deberá identificar mediante programación qué columnas han cambiado. Para ello, recorra en iteración la colección Columns y compare los distintos valores de DataRowVersion.

Para obtener la versión original de un registro

  • Acceda al valor de una columna que se pasa en DataRowVersion de la fila que desea devolver.

    El ejemplo siguiente muestra cómo puede utilizar un valor DataRowVersion para obtener el valor original de un campo CompanyName en un objeto DataRow:

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

Acceso a la versión actual de DataRow

Para obtener la versión actual de un registro

  • Acceda al valor de una columna y agregue un parámetro al índice donde se indique qué versión de una fila desea que se devuelva.

    En el ejemplo siguiente se muestra cómo puede utilizar un valor DataRowVersion para obtener el valor actual de un campo CompanyName en un objeto DataRow:

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