Capitulo 1: clases desconectadas de ADO.NET (Parte 2)

Exportar un DataView a una nueva DataTable
Un DataView se puede utilizar para exportar los datos de un DataTable a otra (con el método ToTable del DataView). Esto puede ser útil cuando se aplican filtros  y se quiere convertir la vista en una nueva DataTable:
---------------------------------VB---------------------------------
Dim export As DataTable = view.ToTable( _
   "MyCarTable", True, "Vin", "Make", "Year")
   '(nombre de la tabla, distinto, nombre de las columnas)
---------------------------------CS--------------------------------- 
DataTable export = view.ToTable(
   "MyCarTable", true, "Vin", "Make", "Year");
//(nombre de la tabla, distinto, nombre de las columnas)
--------------------------------------------------------------------

Seteando distinto (distinct) a true, solo los valores de la vista distintos son guardados.

Usando un DataSet para coordinar el trabajo entre DataTables


Un DataSet es una representación de datos en memoria que contiene una colección de DataTable y DataRelation, no proporciona ninguna de las propiedades de las transacciones (atomicidad, coherencia, aislamiento y durabilidad).

image

Se puede crear el esquema del DataSet mediante programación o mediante la definición de un esquema XML. Los dos DataTable se unen mediante un DataRelation llamado vendors_parts.
---------------------------------VB---------------------------------
'creo el dataset VendorData
   Dim vendorData As New DataSet("VendorData")
   'le agrego la tabla vendors con sus columnas
   Dim vendors As DataTable = vendorData.Tables.Add("Vendors")
   vendors.Columns.Add("Id", GetType(Guid))
   vendors.Columns.Add("Name", GetType(String))
   vendors.Columns.Add("Address1", GetType(String))
   vendors.Columns.Add("Address2", GetType(String))
   vendors.Columns.Add("City", GetType(String))
   vendors.Columns.Add("State", GetType(String))
   vendors.Columns.Add("ZipCode", GetType(String))
   vendors.Columns.Add("Country", GetType(String))
   'le defino la primary key
   vendors.PrimaryKey = New DataColumn() {vendors.Columns("Id")}

   'le agrego la tabla Parts con sus columnas
   Dim parts As DataTable = vendorData.Tables.Add("Parts")
   parts.Columns.Add("Id", GetType(Guid))
   parts.Columns.Add("VendorId", GetType(Guid))
   parts.Columns.Add("PartCode", GetType(String))
   parts.Columns.Add("PartDescription", GetType(String))
   parts.Columns.Add("Cost", GetType(Decimal))
   parts.Columns.Add("RetailPrice", GetType(Decimal))
  
  'le defino la primary key
   parts.PrimaryKey = New DataColumn() {parts.Columns("Id")}

   'creo las relaciones PK y FK
   vendorData.Relations.Add("vendors_parts", _
   vendors.Columns("Id"),parts.Columns("VendorId"))
---------------------------------CS---------------------------------
DataSet vendorData = new DataSet("VendorData");

  DataTable vendors = vendorData.Tables.Add("Vendors");
  vendors.Columns.Add("Id", typeof(Guid));
  vendors.Columns.Add("Name", typeof(string));
  vendors.Columns.Add("Address1", typeof(string));
  vendors.Columns.Add("Address2", typeof(string));
  vendors.Columns.Add("City", typeof(string));
  vendors.Columns.Add("State", typeof(string));
  vendors.Columns.Add("ZipCode", typeof(string));
  vendors.Columns.Add("Country", typeof(string));
  vendors.PrimaryKey = new DataColumn[]{vendors.Columns["Id"]};

  DataTable parts = vendorData.Tables.Add("Parts");
  parts.Columns.Add("Id", typeof(Guid));
  parts.Columns.Add("VendorId", typeof(Guid));
  parts.Columns.Add("PartCode", typeof(string));
  parts.Columns.Add("PartDescription", typeof(string));
  parts.Columns.Add("Cost", typeof(decimal));
  parts.Columns.Add("RetailPrice", typeof(decimal));
  parts.PrimaryKey = new DataColumn[] {parts.Columns["Id"]};

  vendorData.Relations.Add("vendors_parts",
  vendors.Columns["Id"],parts.Columns["VendorId"]);
--------------------------------------------------------------------
¿Qué sucede si el nombre de la tabla está mal escrito?

Se produce una excepción, pero no hasta el tiempo de ejecución. Un mejor enfoque es crear un nuevo DataSet que se hereda del DataSet anterior y agregar una propiedad para cada una de las tablas:
---------------------------------VB---------------------------------
Dim vendorTable As DataTable = vendorData.Vendors
---------------------------------CS---------------------------------
DataTable vendorTable = vendorData.Vendors;
--------------------------------------------------------------------
Con esta sintaxis, se genera un error en tiempo de compilación si el Vendors no esta escrita correctamente. La clase DataSet estándar es un conjunto de datos sin tipo, mientras que el conjunto de datos especializada es un conjunto de datos con tipo.

Puede crear una clase DataSet manualmente, pero es mejor dar una definición de esquemas XML (XSD) para generar la clase DataSet con tipo. VisualStudio incluye una herramienta llamada Editor de DataSet que se puede utilizar para crear y modificar un archivo XSD gráficamente: haciendo clic en el proyecto, clic en Agregar, Nuevo elemento y seleccionar la plantilla de DataSet.
image
 

Eliminación y actualización en cascada

Para realizar eliminaciones en cascada, se puede hacer mediante el establecimiento de DeleteRule de la ForeignKeyConstraint de la tabla secundaria que corresponde a la relación.
Al igual que con la eliminación,se puede configurar ChangeRule a un miembro de la enumeración del artículo para obtener el comportamiento apropiado.

NombreDescripción
NoneNo realiza ninguna acción en las filas relacionadas.
CascadeElimina o actualiza las filas relacionadas. Éste es el valor predeterminado.
SetNullEstablece los valores de las filas relacionadas en DBNull.
SetDefaultEstablece los valores de las filas relacionadas en el valor contenido en la propiedad DefaultValue.
---------------------------------VB---------------------------------
'seteo un delete rule
 Dim fk As ForeignKeyConstraint = parts.Constraints("vendors_parts")
 fk.DeleteRule = Rule.None
---------------------------------CS---------------------------------
 //seteo un delete rule
 ForeignKeyConstraint fk =
 (ForeignKeyConstraint)parts.Constraints["vendors_parts"];
 fk.DeleteRule = Rule.None;
--------------------------------------------------------------------

Utilizando Merge para combinar los datos de un DataSet

En muchas ocasiones, los datos disponibles en un conjunto de datos debe ser combinado con otro conjunto de datos.

La clase DataSet contiene un método llamado de Merge que se puede utilizar para combinar datos de múltiples DataSet. Este tiene varias sobrecargas para combinar los datos de DataSets, DataTables o DataRows.

El ejemplo de como combinar los cambios de un DataSet en otro.
---------------------------------VB---------------------------------
  'Creo un dataset
  Dim masterData As New DataSet("Sales")
  'le agrego las tablas
  Dim people As DataTable = masterData.Tables.Add("People")
  'creo las columnas
  people.Columns.Add("Id", GetType(Guid))
  people.Columns.Add("Name", GetType(String))
  'seteo la PK
  people.PrimaryKey = New DataColumn() {people.Columns("Id")}
  'creo una fila
  people.Rows.Add(Guid.NewGuid(), "Joe")
  'Creo un DataSet temporal y realizo cambios
  Dim tempData As DataSet = masterData.Copy()
  Dim tempPeople As DataTable = tempData.Tables("People")
  'obtengo la info de Joe
  Dim joe As DataRow = tempPeople.Select("Name='Joe'")(0)
  Dim joeId As Guid = CType(joe("Id"), Guid)
  'le modifico el nombre
  joe("Name") = "Joe in Sales"
  'Creo una tabla Order y agrego ordenes para Joe
  Dim orders As DataTable = tempData.Tables.Add("Orders")
  orders.Columns.Add("Id", GetType(Guid))
  orders.Columns.Add("PersonId", GetType(Guid))
  orders.Columns.Add("Amount", GetType(Decimal))
  orders.PrimaryKey = New DataColumn() {orders.Columns("Id")}
  orders.Rows.Add(Guid.NewGuid(), joeId, 100)
  'uno la tabla temporal con la master
  masterData.Merge(tempData, False, MissingSchemaAction.AddWithKey)
---------------------------------CS---------------------------------
 DataSet masterData = new DataSet("Sales");
 DataTable people = masterData.Tables.Add("People");

 people.Columns.Add("Id", typeof(Guid));
 people.Columns.Add("Name", typeof(string));
 people.PrimaryKey = new DataColumn[] { person.Columns["Id"] };

 people.Rows.Add(Guid.NewGuid(), "Joe");
 DataSet tempData = masterData.Copy();

 DataTable tempPeople = tempData.Tables["People"];

 DataRow joe = tempPeople.Select("Name='Joe'")[0];
 Guid joeId = (Guid)joe["Id"];

 joe["Name"] = "Joe in Sales";
 DataTable orders = tempData.Tables.Add("Orders");
 orders.Columns.Add("Id", typeof(Guid));
 orders.Columns.Add("PersonId", typeof(Guid));
 orders.Columns.Add("Amount", typeof(decimal));
 orders.PrimaryKey = new DataColumn[] { orders.Columns["Id"] };
 orders.Rows.Add(Guid.NewGuid(), joeId, 100);
 masterData.Merge(tempData, false, MissingSchemaAction.AddWithKey);
--------------------------------------------------------------------

Este ejemplo crea un Dataset, un DataTable “people” y una persona llamada Joe. Después copia DataSet masterData a un DataSet denominadoTempData. se modifica el DataSet TempData al cambiar el nombre de Joe para "Joe en Ventas", y luego se crea un nuevo DataTable “órdenes” y agrega un pedido.

El método de Merge, tiene tres parámetros:
  • El primer parámetro se pasa el TempData.
  • El segundo parámetro es un valor booleano llamado PreserveChanges, que especifica si las actualizaciones del Dataset TempData debe sobrescribir los cambios realizados en el masterData.
  • El último parámetro es un miembro de la enumeración MissingSchemaAction.

Los valores de la enumeracion MissingSchemaAction son:

Nombre Descripción
AddAgrega las columnas necesarias para completar el esquema.
AddWithKeyAgrega las columnas necesarias e información sobre la clave principal para completar el esquema.
ErrorSi la asignación de columna especificada no existe, se genera InvalidOperationException.
IgnoreOmite las columnas adicionales.

Resumen de la lección

Esta lección proporciona una visión detallada de las clases DataTable y DataSet.
■ Cuando se trabaja con datos desconectados, un DataTable es casi siempre un requisito.
■ Un DataTable contiene DataColumns, que definen el esquema, y DataRows que contienen los datos.
■ DataRow tiene las propiedades  RowState  y DataRowVersion.
■ La propiedad RowState indica si la fila de datos se debe insertar, actualizar o eliminar.
■ El objeto DataTable puede contener hasta tres copias de los datos de DataRow,basado en la propiedad DataRowVersion. Esta característica permite que los datos que se revierta a su estado original, y se puede utilizar al escribir el código para manejar la resolución de conflictos.
■ Para crear una clave pricipal automáticamente, se debe establecer la propiedad AutoIncrement en true, se establece la propiedad AutoIncrementSeed a -1, y establezca la propiedad AutoIncrementStep a -1.
■ Utilice el objeto DataView para ordenar, filtrar una ventana en un DataTable.
■ El DataSet contiene una colección DataTable denominados tablas y una colección DataRelation llamada relaciones.
■ Los datos de otro DataSet, DataTable y los DataRow se pueden combinar en otro Dataset

No hay comentarios:

Publicar un comentario