Compartir a través de


Actualización jerárquica en el desarrollo de .NET Framework

Nota:

La DataSet clase y las clases relacionadas son tecnologías heredadas de .NET Framework de principios de los años 2000 que permiten a las aplicaciones trabajar con datos en memoria mientras las aplicaciones están desconectadas de la base de datos. Las tecnologías son especialmente útiles para las aplicaciones que permiten a los usuarios modificar datos y conservar los cambios de nuevo en la base de datos. Aunque los conjuntos de datos son una tecnología probada de éxito, el enfoque recomendado para las nuevas aplicaciones .NET es usar 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 actualización jerárquica hace referencia al proceso de guardar los datos actualizados (de un conjunto de datos con dos o más tablas relacionadas) de vuelta a una base de datos mientras se mantienen las reglas de integridad referencial. La integridad referencial hace referencia a las reglas de coherencia proporcionadas por las restricciones de una base de datos que controlan el comportamiento de insertar, actualizar y eliminar registros relacionados. Por ejemplo, la integridad referencial exige que se cree un registro de cliente antes de permitir que se realicen pedidos para ese cliente. Para obtener más información sobre las relaciones en conjuntos de datos, consulte Relaciones en conjuntos de datos.

La característica de actualización jerárquica usa un TableAdapterManager para gestionar los TableAdapter elementos de un conjunto de datos tipado. El TableAdapterManager componente es una clase generada por Visual Studio, no un tipo de .NET. Al arrastrar una tabla desde la ventana Orígenes de datos a una página de Windows Forms o WPF, Visual Studio agrega una variable de tipo TableAdapterManager al formulario o página y se ve en el diseñador en la bandeja de componentes. Para obtener información detallada sobre la TableAdapterManager clase, consulte la sección Referencia de TableAdapterManager de TableAdapters.

De forma predeterminada, un conjunto de datos trata las tablas relacionadas como "solo relaciones", lo que significa que no aplica restricciones de clave externa. Puede modificar esa configuración en tiempo de diseño mediante el Diseñador de conjuntos de datos. Seleccione la línea de relación entre dos tablas para abrir el cuadro de diálogo Relación . Los cambios que realice aquí determinarán cómo se comporta el TableAdapterManager al enviar los cambios en las tablas relacionadas de nuevo a la base de datos.

Habilitación de la actualización jerárquica en un conjunto de datos

De forma predeterminada, la actualización jerárquica está habilitada para todos los conjuntos de datos nuevos que se agregan o crean en un proyecto. Active o desactive la actualización jerárquica estableciendo la propiedad Actualización jerárquica de un conjunto de datos con tipo del conjunto de datos en True o False:

Configuración de actualización jerárquica

Creación de una nueva relación entre tablas

Para crear una nueva relación entre dos tablas, en el Diseñador de conjuntos de datos, seleccione la barra de título de cada tabla y, a continuación, haga clic con el botón derecho y seleccione Agregar relación.

Menú de agregar relación para actualización jerárquica

Descripción de las restricciones de clave externa, las actualizaciones en cascada y las eliminaciones

Es importante comprender cómo se crean restricciones de clave externa y comportamiento en cascada en la base de datos en el código del conjunto de datos generado.

De forma predeterminada, las tablas de datos de un conjunto de datos se generan con relaciones (DataRelation) que coinciden con las relaciones de la base de datos. Sin embargo, la relación del conjunto de datos no se genera como una restricción de clave externa. DataRelation se configura como Relation Only sin UpdateRule ni DeleteRule en efecto.

De forma predeterminada, las actualizaciones en cascada y las eliminaciones en cascada se desactivan incluso si la relación de la base de datos se establece con actualizaciones en cascada o eliminaciones en cascada activadas. Por ejemplo, crear un nuevo cliente y un nuevo pedido y, a continuación, intentar guardar los datos puede provocar un conflicto con las restricciones de clave externa definidas en la base de datos. Para obtener más información, consulte Desactivar restricciones al rellenar un conjunto de datos.

Establecer el orden para realizar actualizaciones

Establecer el orden para realizar actualizaciones establece el orden de las inserciones, actualizaciones y eliminaciones individuales necesarias para guardar todos los datos modificados en todas las tablas de un conjunto de datos. Cuando la actualización jerárquica está habilitada, las inserciones se realizan primero, luego se actualizan y, a continuación, se eliminan. TableAdapterManager proporciona una UpdateOrder propiedad que se puede establecer para realizar primero las actualizaciones, después inserta y, a continuación, elimina.

Nota:

Es importante comprender que el orden de actualización es completamente inclusivo. Es decir, cuando se realizan actualizaciones, las inserciones y las eliminaciones se realizan para todas las tablas del conjunto de datos.

Para establecer la UpdateOrder propiedad, después de arrastrar elementos desde la ventana Orígenes de datos a un formulario, seleccione TableAdapterManager en la bandeja de componentes y luego configure la propiedad UpdateOrder en la ventana Propiedades.

Creación de una copia de seguridad de un conjunto de datos antes de realizar una actualización jerárquica

Al guardar datos (llamando al método TableAdapterManager.UpdateAll()), el TableAdapterManager intenta actualizar los datos de cada tabla en una sola transacción. Si se produce un error en alguna parte de la actualización de cualquier tabla, se revierte toda la transacción. En la mayoría de las situaciones, la reversión devuelve la aplicación a su estado original.

Sin embargo, a veces es posible que desee restaurar el conjunto de datos a partir de la copia de seguridad. Un ejemplo de esto puede ocurrir cuando se usan valores de incremento automático. Por ejemplo, si una operación de guardado no se realiza correctamente, los valores de incremento automático no se restablecen en el conjunto de datos y el conjunto de datos continúa creando valores de incremento automático. Esto deja un hueco en la numeración que podría no ser aceptable en su aplicación. En situaciones en las que se trata de un problema, TableAdapterManager proporciona una BackupDataSetBeforeUpdate propiedad que reemplaza el conjunto de datos existente por una copia de seguridad si se produce un error en la transacción.

Nota:

La copia de seguridad solo está en memoria mientras se ejecuta el TableAdapterManager.UpdateAll método . Por lo tanto, no hay acceso mediante programación a este conjunto de datos de copia de seguridad porque reemplaza el conjunto de datos original o sale del ámbito en cuanto el TableAdapterManager.UpdateAll método termina de ejecutarse.

Modificación del código de guardado generado para realizar la actualización jerárquica

Guarde los cambios de las tablas de datos relacionadas del conjunto de datos en la base de datos llamando al TableAdapterManager.UpdateAll método y pasando el nombre del conjunto de datos que contiene las tablas relacionadas. Por ejemplo, ejecute el TableAdapterManager.UpdateAll(NorthwindDataset) método para enviar actualizaciones de todas las tablas de NorthwindDataset a la base de datos back-end.

Después de quitar los elementos de la ventana Orígenes de datos , el código se agrega automáticamente al Form_Load evento para rellenar cada tabla (los TableAdapter.Fill métodos). El código también se agrega al evento de clic del botón Guardar de BindingNavigator para guardar los datos del conjunto de datos de nuevo en la base de datos (método TableAdapterManager.UpdateAll).

El código de guardado generado también contiene una línea de código que llama al CustomersBindingSource.EndEdit método . Más concretamente, llama al método EndEdit del primer BindingSource que se agregó al formulario. En otras palabras, este código solo se genera para la primera tabla que se arrastra desde la ventana Orígenes de datos al formulario. La llamada EndEdit confirma los cambios que están en curso en los controles enlazados a datos que se estén editando en ese momento. Por lo tanto, si un control enlazado a datos aún tiene el foco y hace clic en el botón Guardar, todas las ediciones pendientes en ese control se confirman antes del guardado real (el método TableAdapterManager.UpdateAll).

Nota:

El Diseñador de conjuntos de datos solo agrega el BindingSource.EndEdit código de la primera tabla que se coloca en el formulario. Por lo tanto, debe agregar una línea de código para llamar al BindingSource.EndEdit método para cada tabla relacionada del formulario. Para este tutorial, esto significa que tiene que agregar una llamada al método OrdersBindingSource.EndEdit.

  1. Haga doble clic en el botón Guardar para abrir BindingNavigator en el Editor de Código.

  2. Agregue una línea de código para llamar al OrdersBindingSource.EndEdit método después de la línea que llama al CustomersBindingSource.EndEdit método . El código en el evento de clic del botón Guardar debe ser similar al siguiente:

    this.Validate();
    this.customersBindingSource.EndEdit();
    this.ordersBindingSource.EndEdit();
    this.tableAdapterManager.UpdateAll(this.northwindDataSet);
    

Además de confirmar los cambios en una tabla secundaria relacionada antes de guardar los datos en una base de datos, quizás también tenga que confirmar los registros primarios recién creados antes de agregar nuevos registros secundarios a un conjunto de datos. Es decir, es posible que tenga que agregar el nuevo registro primario (Customer) al conjunto de datos antes de que las restricciones de clave externa permitan agregar nuevos registros secundarios (Orders) al conjunto de datos. Para ello, puede usar el evento BindingSource.AddingNew secundario.

Nota:

Que tenga que confirmar los nuevos registros primarios o no depende del tipo de control que se use para enlazar al origen de datos. En este tutorial, se usan controles individuales para enlazar a la tabla primaria. Esto requiere el código adicional para confirmar el nuevo registro primario. Si los registros primarios se mostraran en su lugar en un control de enlace complejo como DataGridView, esta llamada adicional EndEdit para el registro primario no sería necesaria. Esto se debe a que la funcionalidad de enlace a datos subyacente del control controla la confirmación de los nuevos registros.

Para agregar código para confirmar los registros primarios en el conjunto de datos antes de agregar registros secundarios

  1. Cree un controlador de eventos para el OrdersBindingSource.AddingNew evento.

    • Abra Form1 en la vista de diseño, seleccione OrdersBindingSource en la bandeja de componentes , seleccione Eventos en la ventana Propiedades y, a continuación, haga doble clic en el evento AddingNew .
  2. Agregue una línea de código al controlador de eventos que llama al CustomersBindingSource.EndEdit método . El código del OrdersBindingSource_AddingNew controlador de eventos debe ser similar al siguiente:

    this.customersBindingSource.EndEdit();
    

Referencia de TableAdapterManager

De forma predeterminada, se genera una TableAdapterManager clase cuando se crea un conjunto de datos que contiene tablas relacionadas. Para evitar que se genere la clase, cambie el valor de la Hierarchical Update propiedad del conjunto de datos a false. Al arrastrar una tabla que tiene una relación en la superficie de diseño de una página de Windows Forms o WPF, Visual Studio declara una variable miembro de la clase. Si no usa databinding, debe declarar manualmente la variable.

La TableAdapterManager clase no es un tipo de .NET. Por lo tanto, no puede buscarlo en la documentación. Se crea en tiempo de diseño como parte del proceso de creación del conjunto de datos.

A continuación se muestran los métodos y propiedades usados con frecuencia de la TableAdapterManager clase :

Miembro Descripción
método UpdateAll Guarda todos los datos de todas las tablas de datos.
Propiedad BackUpDataSetBeforeUpdate Determina si se va a crear una copia de seguridad del conjunto de datos antes de ejecutar el método TableAdapterManager.UpdateAll. Booleano.
Propiedad tableNameTableAdapter Representa un TableAdapter. El elemento generado TableAdapterManager contiene una propiedad para cada TableAdapter que administra. Por ejemplo, se genera un conjunto de datos con una tabla de Clientes y Órdenes que incluye un objeto TableAdapterManager que contiene las propiedades CustomersTableAdapter y OrdersTableAdapter.
Propiedad UpdateOrder Controla el orden de los comandos individuales de inserción, actualización y eliminación. Establézcalo en uno de los valores de la TableAdapterManager.UpdateOrderOption enumeración.

De forma predeterminada, el UpdateOrder se establece en InsertUpdateDelete. Esto significa que las inserciones, las actualizaciones y las eliminaciones se realizan para todas las tablas del conjunto de datos.