Esta documentación está archivada y no tiene mantenimiento.

Llenar un DataSet desde un DataAdapter

DataSet de ADO.NET es una representación residente en memoria de datos que proporciona un modelo de programación relacional coherente e independiente del origen de los datos. DataSet representa un conjunto completo de datos que incluye restricciones y tablas, así como relaciones entre estas últimas. Dado que DataSet es independiente del origen de datos, puede incluir datos locales de la aplicación, así como datos de otros muchos orígenes. La interacción con los orígenes de datos existentes se controla mediante el DataAdapter.

La propiedad SelectCommand del DataAdapter es un objeto Command que recupera datos del origen de datos. Las propiedades InsertCommand, UpdateCommand y DeleteCommand de DataAdapter son objetos Command que permiten administrar las actualizaciones de los datos en el origen de datos para reflejar las modificaciones efectuadas en el DataSet. Estas propiedades se describen más detalladamente en Actualizar orígenes de datos con DataAdapters.

El método Fill del DataAdapter se usa para llenar un DataSet con los resultados de la propiedad SelectCommand del DataAdapter. El método Fill acepta como argumentos un DataSet que se debe llenar y un objeto DataTable, o su nombre, que se debe llenar con las filas que devuelve SelectCommand.

El método Fill utiliza el objeto DataReader de forma implícita para devolver los nombres y tipos de columna utilizados para crear las tablas de DataSet, así como los datos para llenar las filas de las tablas de DataSet. Las tablas y columnas sólo se crean cuando no existen; en caso contrario, Fill utiliza el esquema existente de DataSet. Los tipos de columna se crean como tipos de .NET Framework conforme se indica en las tablas que aparecen en Asignar los tipos de datos del proveedor de datos de .NET para los tipos de datos de .NET Framework. No se crean claves principales a menos que existan en el origen de datos y se haya dado el valor MissingSchemaAction.AddWithKey a DataAdapter.MissingSchemaAction. Si el método Fill determina que una tabla tiene clave principal, sobrescribe los datos del DataSet con los del origen de datos en aquellas filas en las que los valores de la columna de clave principal coincidan con los de la fila que devuelve el origen de datos. Si no se detecta ninguna clave principal, los datos se anexan a las tablas del DataSet. Fill utiliza cualquier asignación que pueda existir al llenar el DataSet (vea Configurar las asignaciones de DataTable y DataColumn).

NoteNota

Si SelectCommand devuelve los resultados de una combinación externa (OUTER JOIN), DataAdapter no establecerá un valor PrimaryKey para la tabla DataTable resultante. Es necesario definir PrimaryKey para asegurarse de que las filas duplicadas se resuelven correctamente. Para obtener más información, vea Definir una clave principal para una tabla.

En el ejemplo de código siguiente se crea una instancia de un SqlDataAdapter que utiliza un objeto SqlConnection a la base de datos Northwind de Microsoft SQL Server y llena una DataTable en un DataSet con la lista de clientes. La instrucción SQL y los argumentos SqlConnection pasados al constructor SqlDataAdapter se utilizan para crear la propiedad SelectCommand del SqlDataAdapter.

Ejemplo

// Assumes that connection is a valid SqlConnection object.
string queryString = 
  "SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);

DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
NoteNota

El código que aparece en este ejemplo no abre o cierra el objeto Connection de manera explícita. El método Fill abre de forma implícita el objeto Connection que utiliza el DataAdapter cuando determina que esta conexión no está abierta. Cuando el método Fill ha abierto la conexión, el mismo método la cierra cuando termina de utilizarla. Este hecho simplifica el código cuando se trata de una operación única, como un método Fill o Update. Sin embargo, en el caso de que se estén realizando varias operaciones que necesiten tener abierta una conexión, puede mejorar el rendimiento de la aplicación si llama explícitamente al método Open de Connection, realiza a continuación las operaciones en el origen de datos y, finalmente, llama al método Close de Connection. Es conveniente mantener abiertas las conexiones del origen de datos lo más brevemente posible con el fin de liberar recursos, de manera que estén disponibles para otras aplicaciones cliente.

Varios conjuntos de resultados

Si el DataAdapter encuentra varios conjuntos de resultados, crea varias tablas en el DataSet. Las tablas reciben de forma predeterminada el nombre secuencial TableN, comenzando por "Table" que representa Table0. Si se pasa un nombre de tabla como argumento al método Fill, las tablas reciben de forma predeterminada el nombre secuencial TableNameN, comenzando por "TableName" que representa TableName0.

Llenar un DataSet desde múltiples DataAdapter

Se puede utilizar cualquier cantidad de objetos DataAdapter con un DataSet. Cada DataAdapter se puede utilizar para llenar uno o varios objetos DataTable y para reflejar en el origen de datos correspondiente las actualizaciones que sean necesarias. Se pueden agregar de forma local objetos DataRelation y Constraint al DataSet, de manera que se pueden relacionar datos procedentes de varios orígenes distintos. Por ejemplo, un DataSet puede contener datos de una base de datos de Microsoft SQL Server, una base de datos de IBM DB2 expuesta mediante OLE DB y un origen de datos que genera secuencias XML. Para ocuparse de la comunicación con cada origen de datos se pueden usar uno o varios objetos DataAdapter.

Ejemplo

En el ejemplo de código siguiente se llena una lista de clientes a partir de la base de datos Northwind de Microsoft SQL Server 2000 y una lista de pedidos a partir de la base de datos Northwind almacenada en Microsoft Access 2000. Las tablas de datos llenas se relacionan entre sí mediante DataRelation, con lo que se puede mostrar una lista de clientes con los pedidos que ha realizado cada uno. Para obtener más información sobre objetos DataRelation, vea Agregar una relación entre tablas y Explorar una relación entre tablas.

// Assumes that customerConnection is a valid SqlConnection object.
// Assumes that orderConnection is a valid OleDbConnection object.
SqlDataAdapter custAdapter = new SqlDataAdapter(
  "SELECT * FROM dbo.Customers", customerConnection);
OleDbDataAdapter ordAdapter = new OleDbDataAdapter(
  "SELECT * FROM Orders", orderConnection);

DataSet customerOrders = new DataSet();

custAdapter.Fill(customerOrders, "Customers");
ordAdapter.Fill(customerOrders, "Orders");

DataRelation relation = customerOrders.Relations.Add("CustOrders",
  customerOrders.Tables["Customers"].Columns["CustomerID"],
  customerOrders.Tables["Orders"].Columns["CustomerID"]);

foreach (DataRow pRow in customerOrders.Tables["Customers"].Rows)
{
  Console.WriteLine(pRow["CustomerID"]);
   foreach (DataRow cRow in pRow.GetChildRows(relation))
    Console.WriteLine("\t" + cRow["OrderID"]);
}

Tipo decimal de SQL Server

DataSet almacena de forma predeterminada los datos utilizando tipos de datos de .NET Framework. En la mayor parte de las aplicaciones, estos tipos proporcionan una representación adecuada de la información del origen de datos. Sin embargo, esa representación puede ocasionar problemas cuando el tipo de datos del origen de datos es decimal o numérico de SQL Server. El tipo de datos decimal de .NET Framework permite un máximo de 28 dígitos significativos, mientras que el tipo decimal de SQL Server permite 38 dígitos. Cuando SqlDataAdapter determina, durante una operación Fill, que la precisión de un campo decimal de SQL Server es mayor de 28 caracteres, la fila actual no se agrega a DataTable. En cambio, se produce un evento FillError que le permite decidir si se debe producir o no una pérdida de precisión y tomar las medidas adecuadas. Para obtener más información sobre el evento FillError, vea Trabajar con eventos DataAdapter. Para obtener el valor decimal de SQL Server también, puede utilizar un objeto SqlDataReader y llamar al método GetSqlDecimal.

ADO.NET 2.0 incorpora compatibilidad mejorada para System.Data.SqlTypes en el DataSet. Para obtener más información, vea SqlTypes y el DataSet.

Capítulos de OLE DB

Se pueden usar conjuntos jerárquicos de filas, o capítulos (tipo DBTYPE_HCHAPTER de OLE DB y tipo adChapter de ADO), para llenar un DataSet. Cuando OleDbDataAdapter encuentra una columna que tiene un capítulo, durante una operación Fill, se crea una DataTable para ella y la tabla se llena con las columnas y filas del capítulo. La tabla creada para la columna con capítulo recibe como nombre el de la tabla primaria y el de la columna con capítulo. El nombre tiene el formato "nombreDeTablaPrimariaNombreDeColumnaConCapítulo". Si ya existe en el DataSet una tabla que tenga el nombre de la columna con capítulo, esa tabla se llena con los datos del capítulo. Si ninguna de las columnas de la tabla existente coincide con una de las columnas del capítulo, se agrega una nueva columna a la tabla.

Antes de que se llenen las tablas del DataSet con los datos de las columnas con capítulos, se crea una relación entre las tablas primaria y secundaria del conjunto jerárquico de filas; para ello, se agrega una columna de tipo entero a las tablas primaria y secundaria, se establece la propiedad de incremento automático en la columna de la tabla primaria y se crea una DataRelation entre las columnas agregadas de ambas tablas. Para dar nombre a la relación, se utilizan los nombres de la tabla primaria y de la columna con capítulo con el formato "nombreDeTablaPrimariaNombreDeColumnaConCapítulo".

Tenga en cuenta que la columna relacionada sólo existe en el DataSet. Otras operaciones de llenado que se realicen a continuación desde el origen de datos irán agregando nuevas filas a las tablas en lugar de introducir cambios en las filas ya existentes.

Tenga en cuenta además que, si se utiliza una sobrecarga de DataAdapter.Fill que acepte una tabla DataTable, ésa será la única tabla que se llene. En este caso también se agrega a la tabla una columna de tipo entero y con incremento automático, aunque no se crea ni rellena ninguna tabla secundaria, ni se crea ninguna relación.

En el ejemplo siguiente se utiliza el proveedor MSDataShape para generar un capítulo con la columna de pedidos realizados por cada uno de los clientes de una lista. A continuación se llena con esos datos un DataSet.

using (OleDbConnection connection = new OleDbConnection("Provider=MSDataShape;Data Provider=SQLOLEDB;" +
  "Data Source=(local);Integrated Security=SSPI;Initial Catalog=northwind"))
{
OleDbDataAdapter adapter = new OleDbDataAdapter("SHAPE {SELECT CustomerID, CompanyName FROM Customers} " +
  "APPEND ({SELECT CustomerID, OrderID FROM Orders} AS Orders " +
  "RELATE CustomerID TO CustomerID)", connection);

DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
}

Una vez finalizada la operación Fill, el DataSet contiene dos tablas: Customers y CustomersOrders, donde CustomersOrders representa la columna con capítulo. Se agrega una columna adicional con el nombre Orders a la tabla Customers y una columna adicional con el nombre CustomersOrders a la tabla CustomersOrders. La columna Orders en la tabla Customers se establece con incremento automático. Se crea también una relación DataRelation, CustomersOrders, utilizando las columnas que se han agregado a las tablas donde la tabla Customers es la primaria. Las siguientes tablas muestran algunos ejemplos de los resultados.

TableName: Customers
CustomerID CompanyName Orders

ALFKI

Alfreds Futterkiste

0

ANATR

Ana Trujillo Emparedados y helados

1

TableName: CustomersOrders
CustomerID OrderID CustomersOrders

ALFKI

10643

0

ALFKI

10692

0

ANATR

10308

1

ANATR

10625

1

Vea también

Mostrar: