Sie sind auf Seite 1von 20

UNIVERSIDAD TECNOLGICA NACIONAL Tcnico Superior en Programacin Laboratorio IV ADO.NET Informacin General de ADO.NET ADO.

NET es una evolucin del modelo de acceso a datos de ADO que controla directamente los requisitos del usuario para programar aplicaciones escalables. Se dise especficamente para el Web, teniendo en cuenta la escalabilidad, la independencia y el estndar XML. ADO.NET utiliza algunos objetos ADO, como Connection y Command, y tambin agrega objetos nuevos. Algunos de los nuevos objetos clave de ADO.NET son DataSet, DataReader y DataAdapter. La diferencia ms importante entre esta fase evolucionada de ADO.NET y las arquitecturas de datos anteriores es que existe un objeto, DataSet, que es independiente y diferente de los almacenes de datos. Por ello, DataSet funciona como una entidad independiente. Se puede considerar el objeto DataSet como un conjunto de registros que siempre est desconectado y que no sabe nada sobre el origen y el destino de los datos que contiene. Dentro de un objeto DataSet, de la misma manera que dentro de una base de datos, hay tablas, columnas, relaciones, restricciones, vistas, etc. El objeto DataAdapter es el objeto que se conecta a la base de datos para llenar el objeto DataSet. A continuacin, se vuelve a conectar a la base de datos para actualizar los datos de dicha base de datos a partir de las operaciones realizadas en los datos contenidos en el objeto DataSet. En el pasado, el procesamiento de datos se basaba principalmente en la conexin. Ahora, con el fin de proporcionar a las aplicaciones multinivel mayor eficacia, se est adoptando para el procesamiento de datos un enfoque basado en mensajes que manipulan fragmentos de informacin. En el centro de este enfoque se sita el objeto DataAdapter, que proporciona un puente entre un objeto DataSet y un almacn de datos de origen para recuperar y guardar datos. Para ello, enva solicitudes a los comandos SQL apropiados que se ejecutan en el almacn de datos. El objeto DataSet basado en XML proporciona un modelo de programacin coherente que funciona con todos los modelos de almacenamiento de datos: sin formato, relacional o jerrquico. Funciona sin tener 'conocimiento' del origen de los datos y representa a los datos que contiene como colecciones y tipos de datos. Independientemente del origen de los datos del objeto DataSet, stos se manipulan mediante el mismo conjunto de API estndar expuestas a travs del objeto DataSet y sus objetos subordinados. Aunque el objeto DataSet no tiene conocimiento del origen de sus datos, el proveedor administrado tiene informacin detallada y especfica. La funcin del proveedor administrado es conectar, llenar y almacenar el objeto DataSet desde almacenes de datos (o viceversa). Los proveedores de datos OLE DB y SQL Server de .NET (System.Data.OleDb y System.Data.SqlClient) que forman parte de .Net Framework proporcionan cuatro objetos bsicos: Command, Connection, DataReader y DataAdapter. En el resto de las secciones de este documento, se describir cada parte del objeto DataSet y los proveedores de datos OLE DB y SQL Server de .NET, con el fin de explicar qu son y cmo se pueden utilizar al programar. En las siguientes secciones se presentarn algunos objetos que han evolucionado desde la tecnologa anterior y otros objetos nuevos. Los objetos son los siguientes:

Objetos Connection. Para conectar con una base de datos y administrar las transacciones en una base de datos. Objetos Command. Para emitir comandos SQL a una base de datos. Objetos DataReader. Proporcionan una forma de leer una secuencia de registros de datos slo hacia delante desde un origen de datos SQL Server. Objetos DataSet. Para almacenar datos sin formato, datos XML y datos relacionales, as como para configurar el acceso remoto y programar sobre datos de este tipo. Objetos DataAdapter. Para insertar datos en un objeto DataSet y reconciliar datos de la base de datos.

Nota al trabajar con conexiones a una base de datos, hay dos opciones diferentes: un proveedor de datos de SQL Server de .NET (System.Data.SqlClient) y un proveedor de datos OLE DB de .NET (System.Data.OleDb). En estos ejemplos se utilizar el proveedor de datos SQL Server de .NET. Estn programados para comunicarse directamente con Microsoft SQL Server. El proveedor de datos OLE DB de .NET se utiliza para comunicarse con cualquier proveedor OLE DB (ya que utiliza OLE DB como tecnologa subyacente). Conexiones Para establecer la comunicacin con bases de datos, se utilizan las conexiones y se representan mediante clases especficas de proveedor, como SQLConnection. Los comandos viajan por las conexiones y devuelven conjuntos de resultados en forma de secuencias que puede leer un objeto DataReader o que se pueden insertar en un objeto DataSet.

En el ejemplo siguiente se muestra la forma de crear un objeto de conexin. Las conexiones se pueden abrir explcitamente mediante llamadas al mtodo Open de la conexin; tambin se pueden abrir implcitamente al utilizar un objeto DataAdapter. namespace HowTo.Samples.ADONET { using System; using System.Data.SqlClient; public class adooverview1 { public static void Main() { adooverview1 myadooverview1 = new adooverview1(); myadooverview1.Run(); } public void Run() { SqlConnection mySqlConnection = new SqlConnection("server=(local)\\NetSDK;Trusted_Connection=yes;database=northwind"); try { mySqlConnection.Open(); Console.WriteLine("Conexin con {0} abierta", mySqlConnection.ConnectionString); // Close the connection explicitly mySqlConnection.Close(); Console.WriteLine("Conexin cerrada. Es importante cerrar las conexiones explcitamente."); } catch { Console.WriteLine("No se pudo abrir la conexin con {0}", mySqlConnection.ConnectionString); } } } Comandos Los comandos contienen la informacin que se enva a una base de datos y se representan mediante clases especficas de un proveedor, como SQLCommand. Un comando podra ser una llamada a un procedimiento almacenado, una instruccin UPDATE o una instruccin que devuelve resultados. Tambin es posible utilizar parmetros de entrada o de resultados y devolver valores como parte de la sintaxis del comando. En el ejemplo siguiente se muestra la forma de ejecutar una instruccin INSERT en la base de datos Northwind. namespace HowTo.Samples.ADONET { using System; using System.Data.SqlClient; public class adooverview2 { public static void Main() { adooverview2 myadooverview2 = new adooverview2(); myadooverview2.Run(); } public void Run() { string Message = null; SqlConnection myConnection = new SqlConnection("server=(local)\\NetSDK;Trusted_Connection=yes;database=northwind"); }

SqlCommand mySqlCommand = new SqlCommand("INSERT INTO Customers (CustomerId, CompanyName, ContactName, ContactTitle, Address) Values ('ABC','ABC Company', 'John Smith', 'Owner','One My Way')", myConnection); SqlCommand mySqlCleanup = new SqlCommand("DELETE FROM Customers WHERE CustomerId = 'ABC'", myConnection); try { myConnection.Open(); mySqlCleanup.ExecuteNonQuery(); // remove record that may have been entered previously. mySqlCommand.ExecuteNonQuery(); Message = "Se ha insertado un registro nuevo en la tabla Customers de Northwind."; } catch(Exception e) { Message= "No se pudo insertar el registro: " + e.ToString(); } finally { myConnection.Close(); } Console.Write(Message); } } }

Objetos DataReader El objeto DataReader es, en cierto modo, sinnimo de un cursor de slo lectura y slo hacia delante para datos. La API de DataReader es compatible con datos sin formato y con datos jerrquicos. Cuando se ejecuta un comando en la base de datos, se devuelve un objeto DataReader. El formato del objeto DataReader devuelto es distinto de un conjunto de registros. Por ejemplo, podra utilizarse el objeto DataReader para mostrar los resultados de una lista de bsqueda en una pgina Web. namespace HowTo.Samples.ADONET { using System; using System.Data; using System.Data.SqlClient; public class adooverview3 { public static void Main() { adooverview3 myadooverview3 = new adooverview3(); myadooverview3.Run(); } public void Run() { SqlDataReader myReader = null; SqlConnection mySqlConnection = new SqlConnection("server =(local)\\NetSDK;Trusted_Connection=yes;database=northwind"); SqlCommand mySqlCommand = new SqlCommand("select * from customers", mySqlConnection); try { mySqlConnection.Open(); myReader = mySqlCommand.ExecuteReader(); Console.Write("Customer ID "); Console.WriteLine("Nombre de la compaa"); while (myReader.Read()) { Console.Write(myReader["CustomerID"].ToString() + " "); Console.WriteLine(myReader["CompanyName"].ToString()); }

} catch(Exception e) { Console.WriteLine(e.ToString()); } finally { if (myReader != null) myReader.Close(); if (mySqlConnection.State == ConnectionState.Open) mySqlConnection.Close();

} } } }

Objetos DataSet y DataAdapter Objetos DataSet El objeto DataSet es similar al objeto Recordset de ADO, pero ms eficaz y con una diferencia importante: DataSet siempre est desconectado. El objeto DataSet representa a una memoria cach de datos, con estructuras anlogas a las de una base de datos, como tablas, columnas, relaciones y restricciones. Sin embargo, aunque se puede utilizar un objeto DataSet como una base de datos (y su comportamiento es muy similar), es importante recordar que los objetos DataSet no interactan directamente con bases de datos ni con otros datos de origen. Esto permite al programador trabajar con un modelo de programacin que siempre es coherente, independientemente de dnde resida el origen de datos. En los objetos DataSet se pueden colocar datos provenientes de una base de datos, un archivo XML, cdigo o informacin escrita por el usuario. A continuacin, a medida que se realizan cambios en el objeto DataSet, se puede hacer un seguimiento y una comprobacin de los cambios antes de actualizar los datos de origen. El mtodo GetChanges del objeto DataSet crea en realidad otro objeto DataSet que slo contiene los cambios realizados en los datos. Posteriormente, un objeto DataAdapter u otros objetos, utilizan este objeto DataSet para actualizar el origen de datos original. El objeto DataSet tiene muchas caractersticas de XML, incluida la capacidad de producir y consumir datos XML y esquemas XML. Los esquemas XML se pueden utilizar para describir esquemas intercambiables a travs de servicios Web. De hecho, un objeto DataSet con un esquema puede compilarse con seguridad de tipos y finalizacin automtica de instrucciones. Objetos DataAdapter (OLEDB/SQL) El objeto DataAdapter funciona como un puente entre el objeto DataSet y los datos de origen. El uso del objeto SqlDataAdapter especfico del proveedor (junto con los objetos SqlCommand y SqlConnection asociados) permite aumentar el rendimiento global al trabajar con bases de datos de Microsoft SQL Server. Para otras bases de datos compatibles con OLE DB, se debe utilizar el objeto OleDbDataAdapter y los objetos OleDbCommand y OleDbConnection asociados. El objeto DataAdapter utiliza comandos para actualizar el origen de datos despus de hacer modificaciones en el objeto DataSet. Si se utiliza el mtodo Fill del objetoDataAdapter, se llama al comando SELECT; si se utiliza el mtodo Update se llama al comando INSERT, UPDATE o DELETE para cada fila modificada. Es posible establecer explcitamente estos comandos con el fin de controlar las instrucciones que se utilizan en tiempo de ejecucin para resolver cambios, incluido el uso de procedimientos almacenados. En escenarios ad-hoc, un objeto CommandBuilder puede generarlos en tiempo de ejecucin a partir de una instruccin de seleccin. Sin embargo, para generar en tiempo de ejecucin hay que hacer un viaje de ida y vuelta adicional al servidor con el fin de recopilar los metadatos necesarios; por tanto, si se proporcionan explcitamente los comandos INSERT, UPDATE y DELETE en tiempo de diseo, el rendimiento en tiempo de ejecucin mejorar.

SqlConnection myConnection = new SqlConnection("server= (local)\VSdotNET;Trusted_Connection=yes;database=northwind"); SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("select * from customers", myConnection); mySqlDataAdapter.InsertCommand.CommandText = "sp_InsertCustomer"; mySqlDataAdapter.InsertCommand.CommandType = CommandType.StoredProcedure; mySqlDataAdapter.DeleteCommand.CommandText = "sp_DeleteCustomer"; mySqlDataAdapter.DeleteCommand.CommandType = CommandType.StoredProcedure; mySqlDataAdapter.UpdateCommand.CommandText = "sp_UpdateCustomers"; mySqlDataAdapter.UpdateCommand.CommandType = CommandType.StoredProcedure; mySqlDataAdapter.Update(myDataSet); Los registros se asignan a los comandos correspondientes de la forma apropiada.

Figura: Objetos DataAdapter y DataSet En el ejemplo siguiente se ilustra la carga de un objeto DataAdapter a travs de una instruccin SELECT. A continuacin, se actualizan, eliminan y agregan algunos registros en el objeto DataSet. Por ltimo, se devuelven las actualizaciones a la base de datos de origen a travs del objeto DataAdapter. En la pgina, se muestran los comandos DeleteCommand, InsertCommand y UpdateCommand creados. Tambin se ilustra el uso de varios objetos DataAdapter para cargar varias tablas (Customers y Orders) en el objeto DataSet. namespace HowTo.Samples.ADONET { using System; using System.Data; using System.Data.SqlClient; public class adooverview4 { public static void Main() { adooverview4 myadooverview4 = new adooverview4(); myadooverview4.Run(); } public void Run() { // Create a new Connection and SqlDataAdapter SqlConnection myConnection = new SqlConnection("server= (local)\\NetSDK;Trusted_Connection=yes;database=northwind"); SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("Select * from Region", myConnection); SqlParameter workParam = null; // Restore database to it's original condition so sample will work correctly. Cleanup(); // Build the insert Command mySqlDataAdapter.InsertCommand = new SqlCommand("Insert into Region (RegionID, RegionDescription) VALUES (@RegionID, @RegionDescription)", myConnection); workParam = mySqlDataAdapter.InsertCommand.Parameters.Add("@RegionID", SqlDbType.Int); workParam.SourceColumn = "RegionID"; workParam.SourceVersion = DataRowVersion.Current; workParam = mySqlDataAdapter.InsertCommand.Parameters.Add("@RegionDescription", SqlDbType.NChar, 50); workParam.SourceVersion = DataRowVersion.Current; workParam.SourceColumn = "RegionDescription"; // Build the update command mySqlDataAdapter.UpdateCommand = new SqlCommand("Update @RegionDescription WHERE RegionID = @RegionID" , myConnection); Region Set RegionDescription =

workParam = mySqlDataAdapter.UpdateCommand.Parameters.Add("@RegionID", SqlDbType.Int); workParam.SourceColumn = "RegionID"; workParam.SourceVersion = DataRowVersion.Original; workParam = mySqlDataAdapter.UpdateCommand.Parameters.Add("@RegionDescription", SqlDbType.NChar, 50); workParam.SourceVersion = DataRowVersion.Current; workParam.SourceColumn = "RegionDescription"; DataSet myDataSet = new DataSet(); // Set the MissingSchemaAction property to AddWithKey because Fill will not cause primary key & unique key information to be retrieved unless AddWithKey is specified. mySqlDataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey; mySqlDataAdapter.Fill(myDataSet, "Region"); DataRow myDataRow1 = myDataSet.Tables["Region"].Rows.Find(2); myDataRow1[1] = "Se ha cambiado la descripcin de esta regin."; DataRow myDataRow2 = myDataSet.Tables["Region"].NewRow(); myDataRow2[0] = 901; myDataRow2[1] = "Regin nueva"; myDataSet.Tables["Region"].Rows.Add(myDataRow2); try { mySqlDataAdapter.Update(myDataSet, "Region"); Console.Write("El conjunto de datos se actualiz correctamente."); } catch(Exception e) { Console.Write(e.ToString()); }

public void Cleanup() { SqlConnection myConnection = new SqlConnection("server= (local)\\NetSDK;Trusted_Connection=yes;database=northwind"); try { // Restore database to it's original condition so sample will work correctly. myConnection.Open(); SqlCommand CleanupCommand = new SqlCommand("DELETE FROM Region WHERE RegionID = '901'", myConnection); CleanupCommand.ExecuteNonQuery(); } catch(Exception e) { Console.Write(e.ToString()); } finally { myConnection.Close(); } } } } Resumen 1. La tecnologa ADO.NET, integrada en .Net Framework, es el siguiente estado de evolucin de ADO. Se dise teniendo en cuenta los modelos multinivel, la independencia y el estndar XML. Para estos escenarios se proporcionan dos objetos nuevos, DataSet y DataAdapter. Se puede utilizar ADO.NET para obtener datos de una secuencia o para almacenar datos en una memoria cach a fin de realizar actualizaciones. La documentacin contiene mucha ms informacin acerca de ADO.NET. Hay que tener en cuenta que se puede ejecutar un comando directamente en la base de datos para realizar inserciones, actualizaciones y eliminaciones. Para insertar, actualizar o eliminar datos no hay que colocarlos primero en un objeto DataSet. Adems, se puede utilizar un objeto DataSet para enlazar con los datos, examinarlos y explorar sus relaciones.

2.
3. 4.

5. 6.

Ejecutar un comando

Los comandos se ejecutan en bases de datos con el fin de realizar acciones en almacenes de datos. Por ejemplo, sera posible ejecutar un comando para insertar o eliminar datos. Los comandos incluyen cualquier comando que se pueda ejecutar en una base de datos y, si se trata de un comando OleDbCommand, puede ser especfico del almacn de datos. Por ejemplo, se puede emitir una llamada a un procedimiento almacenado para un comando o, quizs, un comando para "set quoted_identifier on". Independientemente de cul sea el comando, se puede utilizar el objeto OleDbCommand o SqlCommand para ejecutar el comando en el almacn de datos del servidor. En la tecnologa tradicional de ADO se pueden emitir comandos a travs de los objetos Command, Connection y Recordset. En ADO.NET, el nico objeto que ejecuta comandos es Command. Para emitir un comando en una base de datos, el objeto Command debe tener dos elementos bsicos: un objeto Connection y un objeto CommandText, que se pueden establecer en el constructor. Para ejecutar el comando, es necesario abrir el objeto Connection ,que no debe estar en estado de bsqueda: String InsertCmdString; InsertCmdString = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'Description')"; SqlCommand mySqlCommand = new SqlCommand(InsertCmdString, myConnection); En este tema se trata la ejecucin de comandos que no generan resultados. Para ejecutar un comando que no devuelve resultados, hay que llamar al mtodo ExecuteNonQuery. mySqlCommand.ExecuteNonQuery();

Los objetos OleDbCommand y SqlCommand tienen colecciones de parmetros que presentan el mismo comportamiento que las colecciones de parmetros de ADO. Se pueden transferir los parmetros en lnea: mySqlCommand.CommandText = "myStoredProc 'CustId'";

O se puede utilizar la coleccin Parameters: workParam = mySqlCommand.Parameters.Add("@CustomerID", SQLDataType.NChar, 5); workParam.Value = "NewID"; El siguiente ejemplo muestra como insertar un comando insert usando SqlCommand. namespace HowTo.Samples.ADONET { using using using using System; System.Data; System.Data.SqlClient; System.Data.Common;

public class executingacommand { public static void Main() { executingacommand myexecutingacommand = new executingacommand(); myexecutingacommand.Run(); } public void Run() { SqlConnection myConnection = new SqlConnection("server= (local)\\NetSDK;Trusted_Connection=yes;database=northwind"); SqlCommand myCommand = new SqlCommand(); SqlTransaction myTrans; // Open the connection. myConnection.Open(); // Assign the connection property. myCommand.Connection = myConnection; // Begin the transaction. myTrans = myConnection.BeginTransaction();

// Assign transaction object for a pending local transaction myCommand.Transaction = myTrans; try { // Restore database to near it's original condition so sample will work correctly. myCommand.CommandText = "DELETE FROM Region WHERE (RegionID = 100) OR (RegionID = 101)"; myCommand.ExecuteNonQuery(); // Insert the first record. myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'MidWestern')"; myCommand.ExecuteNonQuery(); // Insert the second record. myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'MidEastern')"; myCommand.ExecuteNonQuery(); myTrans.Commit(); Console.WriteLine("Ambos registros se han escrito en la base de datos."); } catch(Exception e) { myTrans.Rollback(); Console.WriteLine(e.ToString()); Console.WriteLine("Ninguno de los registros se ha escrito en la base de datos."); } finally { myConnection.Close(); }

} } }

Obtener parmetros de resultados de un procedimiento almacenado Algunos procedimientos almacenados devuelven valores a travs de parmetros. Cuando un parmetro de una instruccin SQL o un procedimiento almacenado est declarado como parmetro de resultados ("out"), se devuelve su valor al llamador. El valor se almacena en un parmetro de la coleccin Parameters de los objetos OleDbCommand o SqlCommand. A diferencia de lo que ocurre en el ejemplo siguiente, cuando no se establecen ni la conexin ni el nombre del comando, se pueden establecer los parmetros, pero ser necesario crear la coleccin de parmetros y definir los tipos esperados. workParam = myCommand.Parameters.Add("@CustomerID", SQLDataType.NChar(5); workParam.Value = "CUSTID"; En el siguiente ejemplo se muestra la forma de utilizar un procedimiento almacenado que devuelva parmetros de resultados. El comando se ejecuta para crear un procedimiento almacenado en la base de datos Northwind. namespace HowTo.Samples.ADONET { using System; using System.Data; using System.Data.SqlClient; public class outparamswithacommand { public static void Main() { outparamswithacommand myoutparamswithacommand = new outparamswithacommand(); myoutparamswithacommand.Run(); } public void Run() { String MsgString = null;

// Create a new Connection and SqlDataAdapter SqlConnection myConnection SqlConnection("server=(local)\\NetSDK;Trusted_Connection=yes;database=northwind"); = new

// Create stored procedure with out parameter try { SqlCommand CreateProcCommand = new SqlCommand("CREATE PROCEDURE GetCompanyName @CustomerId nchar(5), @CompanyName nchar(40) out as select @CompanyName = CompanyName from Customers where CustomerId = @CustomerId",myConnection); SqlCommand DropProcCommand = new SqlCommand("IF EXISTS (SELECT name FROM sysobjects WHERE name = 'GetCompanyName' AND type = 'P') DROP PROCEDURE GetCompanyName", myConnection); myConnection.Open(); DropProcCommand.ExecuteNonQuery(); // remove procedure if it exists CreateProcCommand.ExecuteNonQuery(); // create procedure SqlCommand myCommand = new SqlCommand("GetCompanyName", myConnection); myCommand.CommandType = CommandType.StoredProcedure; // Fill the parameters collection based upon stored procedure. SqlParameter workParam = null; workParam = myCommand.Parameters.Add("@CustomerID", SqlDbType.NChar, 5); // ParameterDirection.Input is the default for the Direction property. Thus the following line is not // needed here. To set the Direction property to its default value, use the following line. // workParam.Direction = ParameterDirection.Input; workParam = myCommand.Parameters.Add("@CompanyName", SqlDbType.NChar, 40); workParam.Direction = ParameterDirection.Output; myCommand.Parameters["@CustomerID"].Value = "ALFKI"; myCommand.ExecuteNonQuery(); MsgString = "Nombre de la compaa = " + myCommand.Parameters["@CompanyName"].Value.ToString(); } catch(Exception e) { MsgString = e.ToString(); } finally { myConnection.Close(); } } } } Llenar un objeto DataSet a partir de una base de datos El hecho de recuperar datos de una base de datos y manipularlos es ms fcil que nunca. Si desea mostrar los resultados de una base de datos como una secuencia de datos de slo lectura y slo hacia delante, es posible ejecutar un comando y recuperar los resultados mediante el objeto DataReader. En lo que se refiere a operaciones ms interactivas, como enlazar datos, recorrer datos o la configuracin remota de los resultados de una consulta de base de datos, es posible colocar los resultados en un objeto DataSet, de la forma mostrada en este ejemplo. El concepto ms importante que hay que recordar es que el objeto DataSet es una estructura de datos independiente y distinta de un almacn de datos. Aunque en el ejemplo se obtienen datos desde una base datos, no importa cul sea su origen porque el objeto DataSet siempre presentar un modelo de programacin coherente. Se trata de una coleccin de datos sencilla, con caractersticas de base de datos relacional. No se incluyen mtodos Load, Open ni Execute, ya que no se sabe de dnde provienen los datos. En esta seccin se describe la forma de utilizar un objeto SqlDataAdapter para cargar en el objeto DataSet datos de una base de datos. Un objeto SqlDataAdapter puede utilizarse para recuperar datos de una base de datos, pero tambin se puede utilizar para insertar datos en la base de datos. En esta seccin se tratar la obtencin de datos. El primer paso es crear un objeto SqlDataAdapter. Esto se hace de la misma manera que se crea un objeto SqlCommand. Console.Write(MsgString);

String SelectCmdString = "select * from customers"; SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(SelectCmdString, myConnection); //...or this can also be done as follows: SqlCommand mySelectCommand = New SqlCommand("select * from customers", myConnection); SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(mySelectCommand);

Los objetos SqlDataAdapter y SqlCommand son muy similares, con la diferencia de los mtodos Fill y Update. El mtodo Fill llena un objeto DataSet. El mtodo Update recoge los cambios realizados en un objeto DataSet y los aplica en la base de datos. Para ello se utilizan cuatro comandos especificados en el objeto DataAdapter. Estos comandos son: SelectCommand, UpdateCommand, InsertCommand y DeleteCommand. Es posible establecer explcitamente estos comandos para controlar las instrucciones que se utilizan en tiempo de ejecucin con el fin de resolver cambios, incluido el uso de procedimientos almacenados. En escenarios ad-hoc, un objeto CommandBuilder puede generarlos en tiempo de ejecucin a partir de una instruccin de. Sin embargo, para generar en tiempo de ejecucin hay que hacer un viaje de ida y vuelta adicional al servidor a fin de recopilar los metadatos necesarios; por tanto, si se proporcionan explcitamente los comandos de insercin, actualizacin y eliminacin en tiempo de diseo, el rendimiento en tiempo de ejecucin ser mayor. NOTA: Visual Studio ayuda en gran medida a establecer objetos SqlDataAdapter y DataSet, y crea procedimientos almacenados de forma prcticamente automtica. Estudie esta caracterstica mediante los objetos ComponentDesigner y Database. Cuando se haya establecido el objeto SqlDataAdapter, se le podr pasar un objeto DataSet para llenarlo: myDataSet = new DataSet(); mySqlDataAdapter.Fill(myDataSet,"Customers"); Ahora el objeto DataSet contiene el resultado de la consulta. De hecho, puede contener los resultados de varias consultas e incluso relacionarlos. Como contiene varios resultados, el objeto DataSet contiene un conjunto de tablas. Hay que tener en cuenta que el mtodo Fill utiliza "Customers" como segundo argumento. Se trata del nombre de la tabla que se va a llenar en el objeto DataSet. Si la tabla no existe, se crea. Como los datos se almacenan en una coleccin de filas de la tabla, es posible utilizar fcilmente una instruccin foreach para recorrer las filas: foreach (DataRow myDataRow in myDataSet.Tables["Customers"].Rows) { Console.WriteLine(myDataRow["CustomerId"].ToString()); } De hecho, tambin se puede utilizar la misma instruccin foreach para recorrer las columnas. En el siguiente ejemplo se muestra la combinacin de todo el cdigo de este documento. namespace HowTo.Samples.ADONET { using System; using System.Data; using System.Data.SqlClient; public class gettingdata { public static void Main() { gettingdata mygettingdata = new gettingdata(); mygettingdata.Run(); } public void Run() { SqlConnection myConnection = new SqlConnection("server= (local)\\NetSDK;Trusted_Connection=yes;database=northwind"); SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("select * from customers", myConnection); try { DataSet myDataSet = new DataSet(); mySqlDataAdapter.Fill(myDataSet,"Customers"); foreach (DataRow myDataRow in myDataSet.Tables["Customers"].Rows)

{ } Console.WriteLine(myDataRow["CustomerId"].ToString()); } catch(Exception e) { Console.WriteLine(e.ToString()); }

} } }

Actualizar una base de datos a partir de un objeto DataSet En este tema se ilustra la forma de actualizar datos de una base de datos mediante un objeto DataSet. Algunos de los temas que se explican en Llenar un objeto DataSet a partir de una base de datos son la carga de un objeto DataSet a partir de una base de datos y la diferencia e independencia entre un objeto DataSet y una base de datos. Cuando se haya cargado el objeto DataSet, se podrn modificar los datos y el objeto DataSet har un seguimiento de los cambios. El objeto DataSet se puede considerar una cach en memoria de datos obtenidos a partir de una base de datos. El objeto DataSet contiene un conjunto de tablas, relaciones y restricciones. En este ejemplo se muestra la forma de utilizar el mtodo Add en el objeto DataTable para agregar datos nuevos a un objeto DataSet. El mtodo Add utiliza una matriz de las columnas de datos esperadas o un objeto DataRow. // Create a new Connection and SqlDataAdapter SqlConnection myConnection = SqlConnection("server=(local)\\VSdotNET;Trusted_Connection=yes;database=northwind"); SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("Select * from Customers", myConnection); DataSet myDataSet = new DataSet(); DataRow myDataRow; // Create command builder. This line automatically generates the update commands for you, so you don't // have to provide or create your own. SqlCommandBuilder mySqlCommandBuilder = new SqlCommandBuilder(mySqlDataAdapter); // Set the MissingSchemaAction property to AddWithKey because Fill will not cause primary // key & unique key information to be retrieved unless AddWithKey is specified. mySqlDataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey; mySqlDataAdapter.Fill(myDataSet, "Customers"); myDataRow = myDataSet.Tables["Customers"].NewRow(); myDataRow["CustomerId"] = "NewID"; myDataRow["ContactName"] = "New Name"; myDataRow["CompanyName"] = "New Company Name"; myDataSet.Tables["Customers"].Rows.Add(myDataRow); new

Hay que tener en cuenta que el objeto DataTable debe devolver un objeto DataRow a travs del mtodo NewRow. El mtodo devuelve un objeto DataRow con el esquema apropiado del objeto DataTable. El nuevo objeto DataRow ser independiente de la tabla hasta que se agregue a la coleccin RowsCollection. Para modificar datos de un objeto DataRow hay que tener acceso al objeto DataRow. Se puede utilizar el ndice de la fila en la coleccin RowsCollection mediante la propiedad Rows: myDataSet.Tables["Customers"].Rows[0]["ContactName"]="Peach"; Tambin se puede tener acceso a una fila especfica a travs del valor de la clave principal: DataRow myDataRow1 = myDataSet.Tables["Customers"].Rows.Find("ALFKI"); myDataRow1["ContactName"]="Peach"; donde "ALFKI" corresponde al valor de la clave principal "CustomerID" de la tabla "Customers". Cuando se utiliza el objeto SqlDataAdapter, la clave se establece a partir de la base de datos. Tambin se puede establecer la clave si no se utiliza la base de datos mediante la propiedad PrimaryKey.

Utilice el mtodo Delete para quitar el objeto Row. Hay que tener en cuenta que se produce una eliminacin lgica en el objeto DataSet, que slo ser una eliminacin definitiva cuando se actualice la base de datos a partir del objeto DataSet. De forma similar, se puede utilizar RejectChanges en el objeto DataSet, en cuyo caso se restaurar el objeto Row. myDataSet.Tables["Customers"].Rows[0].Delete(); Se mantendrn en la fila los valores originales y los valores nuevos. El evento RowChanging permite tener acceso a valores nuevos y valores originales con el fin de decidir si se desea seguir adelante con la modificacin. Como se mantienen valores nuevos y valores originales, se pueden establecer escenarios como el bloqueo optimista o cambios de clave. Antes de devolver los datos enviados a la base de datos, es necesario configurar los comandos InsertCommand, UpdateCommand y DeleteCommand para cotejar los cambios en la base de datos. En escenarios limitados se puede utilizar la clase SqlCommandBuilder para generar automticamente estos comandos de la forma mostrada en el siguiente ejemplo: SqlCommandBuilder mySqlCommandBuilder =new SqlCommandBuilder(mySqlDataAdapter); Para enviar los datos desde el objeto DataSet a la base de datos, hay que utilizar el mtodo Update en el objeto SqlDataAdapter. mySqlDataAdapter.Update(myDataSet, "Customers"); En el siguiente ejemplo se muestra la forma de obtener datos de una base de datos mediante un objeto SqlDataAdapter, modificar los datos dentro del objeto DataSet y despus devolverlos a la base de datos a travs del objeto SqlDataAdapter. namespace HowTo.Samples.ADONET { using System; using System.Data; using System.Data.SqlClient; public class updatingdata { public static void Main() { updatingdata myupdatingdata = new updatingdata(); myupdatingdata.Run(); } public void Run() { SqlConnection myConnection = SqlConnection("server=(local)\\NetSDK;Trusted_Connection=yes;database=northwind"); SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("select * from customers", myConnection); SqlDataAdapter mySqlDataAdapter1 = new SqlDataAdapter("select * from orders", myConnection); // Restore database to it's original condition so sample will work correctly. Cleanup(); try { DataSet myDataSet = new DataSet(); DataRow myDataRow; // Create command builder. This line automatically generates the update commands for you, so you don't // have to provide or create your own. SqlCommandBuilder mySqlCommandBuilder = new SqlCommandBuilder(mySqlDataAdapter); // Set the MissingSchemaAction property to AddWithKey because Fill will not cause primary // key & unique key information to be retrieved unless AddWithKey is specified. mySqlDataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey; mySqlDataAdapter1.MissingSchemaAction = MissingSchemaAction.AddWithKey; mySqlDataAdapter.Fill(myDataSet,"Customers"); Console.WriteLine("Se han cargado los datos de la tabla Customers en el conjunto de datos."); mySqlDataAdapter1.Fill(myDataSet,"Orders"); Console.WriteLine("Datos de la tabla Orders cargados en el conjunto de datos."); new

// ADD RELATION myDataSet.Relations.Add("CustOrders",myDataSet.Tables["Customers"].Columns["CustomerId"],myDataSet.Tables ["Orders"].Columns["CustomerId"]); // EDIT myDataSet.Tables["Customers"].Rows[0]["ContactName"]="Melocotn"; // ADD myDataRow = myDataSet.Tables["Customers"].NewRow(); myDataRow["CustomerId"] ="NewID"; myDataRow["ContactName"] = "Nuevo nombre"; myDataRow["CompanyName"] = "Nuevo nombre de compaa"; myDataSet.Tables["Customers"].Rows.Add(myDataRow); Console.WriteLine("Se insert una fila nueva en la tabla Customers."); // Update Database with SqlDataAdapter mySqlDataAdapter.Update(myDataSet, "Customers"); Console.WriteLine("Actualizacin enviada a la base de datos."); Console.WriteLine("El procesamiento del conjunto de datos se complet correctamente."); } catch(Exception e) { Console.WriteLine(e.ToString()); }

SqlConnection myConnection SqlConnection("server=(local)\\NetSDK;Trusted_Connection=yes;database=northwind");

public void Cleanup() {

new

try { // Restore database to it's original condition so sample will work correctly. myConnection.Open(); SqlCommand CleanupCommand = new SqlCommand("DELETE FROM Customers WHERE CustomerId = 'NewID'", myConnection); CleanupCommand.ExecuteNonQuery(); } catch (Exception e) { Console.WriteLine(e.ToString()); } finally { myConnection.Close(); } } } } Utilizar transacciones de base de datos Las transacciones de base de datos se utilizan para controlar la confirmacin de datos en bases de datos. Por ejemplo, en los procedimientos estndar de cuentas, es necesario retirar fondos de una cuenta e ingresarlos a su vez en otra. Como los equipos pueden sufrir interrupciones de funcionamiento (por interrupcin del suministro elctrico, problemas de red, etc.), podra darse el caso de que se actualizara o agregara un registro determinado, pero no el otro. Para evitar estas situaciones, se utilizan transacciones. Las transacciones de ADO.NET se controlan de la misma manera que en ADO, en el nivel de la base de datos y, para ello, la base de datos debe ser compatible con el uso de transacciones. Existen tres comandos bsicos para las transacciones: BeginTransaction, Commit y Rollback. BeginTransaction marca el principio de una transaccin. Todo lo que ocurra entre la ejecucin del comando BeginTransaction y la del siguiente comando (ya sea Rollback o Commit) se considerar como parte de la transaccin. El siguiente fragmento de cdigo ilustra el uso de las transacciones. SqlConnection myConnection = new SqlConnection("server= (local)\\VSdotNET;Trusted_Connection=yes;database=northwind"); SqlCommand myCommand = new SqlCommand(); SqlTransaction myTrans;

// Open the connection. myConnection.Open(); // Assign the connection property. myCommand.Connection = myConnection; // Begin the transaction. myTrans = myConnection.BeginTransaction(); // Assign transaction object for a pending local transaction myCommand.Transaction = myTrans; try { // Restore database to near its original condition so sample will work correctly. myCommand.CommandText = "DELETE FROM Region WHERE (RegionID = 100) OR (RegionID = 101)"; myCommand.ExecuteNonQuery(); // Insert the first record. myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (100, 'MidWestern')"; myCommand.ExecuteNonQuery(); // Insert the second record. myCommand.CommandText = "Insert into Region (RegionID, RegionDescription) VALUES (101, 'MidEastern')"; myCommand.ExecuteNonQuery(); myTrans.Commit(); Console.WriteLine("Both Records are written to the database!");

} catch(Exception e) { myTrans.Rollback(); Console.WriteLine(e.ToString()); Console.WriteLine("Neither record is written to the database!"); } finally { myConnection.Close(); }

En el ejemplo se muestra que si no se realiza correctamente la insercin, se deshacen las dos operaciones para volver al estado original. Si se realizan las dos correctamente, se confirma la transaccin. Al igual que ocurre en la tecnologa ADO tradicional, se pueden controlar transacciones a travs del objeto connection. De hecho, el uso de una conexin OleDbConnection se basa en el mismo modelo de transacciones OLE DB subyacente. Por tanto, si era posible confirmar transacciones en la base de datos con la tecnologa ADO tradicional, tambin se podrn confirmar con ADO.NET. En el siguiente fragmento de cdigo se ilustra el uso de SqlConnection y SqlCommand para insertar dos registros en la tabla "Region". Si uno de los dos no se ejecuta correctamente, se deshacen los cambios. El objeto DataSet tambin tiene un modelo de confirmaciones (AcceptChanges, RejectChanges), pero no afecta a la base de datos. El modelo de confirmacin se utiliza para el almacenamiento de datos en cach, nicamente en el caso del objeto DataSet. Para enviar los datos desde el objeto DataSet a la base de datos, hay que utilizar el mtodo Update del objeto SqlDataAdapter Controlar errores Adems de proporcionar las funciones Try/Catch y las excepciones, la nueva arquitectura de datos de ADO.NET permite agregar mensajes de error a cada fila de datos de un objeto DataSet. Los objetos SqlDataAdapter asocian mensajes de error a las filas si no se pueden realizar correctamente actualizaciones u otras acciones. Adems, permiten filtrar por aquellas filas que producen error para presentarlas al usuario o pasarlas a funciones de control de errores. Los errores se conservan con el objeto DataSet an cuando se transfieran mediante XML o servicios Web de XML. Es posible utilizar la propiedad RowError para establecer el mensaje de error de un objeto DataRow perteneciente a un objeto DataSet. myDataSet.Tables["Customers"].Rows[0].RowError = "An error was added"; myDataSet.Tables["Customers"].Rows[1].RowError = "This is another error message";

Ahora es posible examinar el error en un objeto DataTable con el mtodo GetErrors(). Tambin se puede hacer una prueba de deteccin de errores con HasErrors.

if ( myDataSet.Tables["Customers"].HasErrors ) { DataRow[] ErrDataRows = myDataSet.Tables["Customers"].GetErrors(); Console.WriteLine("DataTable " + myDataSet.Tables["Customers"].TableName ErrDataRows.Length.ToString() + " Error(s)!");

"

has

"

for (int i = 0; i <= ErrDataRows.Length -1; i++) { Console.WriteLine("Row Error for row " + ErrDataRows[i]["CustomerID"].ToString() + " -- Error Msg=" + ErrDataRows[i].RowError); } } else { Console.WriteLine("================="); Console.WriteLine("DataTable " + myDataSet.Tables["Customers"].TableName + " Has no errors"); }

En el ejemplo siguiente se carga un objeto DataSet, se generan algunos errores y despus de muestran los errores de las filas. namespace HowTo.Samples.ADONET { using System; using System.Data; using System.Data.SqlClient; public class handleerrors { public static void Main() { handleerrors myhandleerrors = new handleerrors(); myhandleerrors.Run(); } public void Run() { // Create a new Connection and SqlDataAdapter SqlConnection myConnection = new SqlConnection("server= (local)\\NetSDK;Trusted_Connection=yes;database=northwind"); SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("select * from customers", myConnection); // Create the new instance of the DataSet DataSet myDataSet = new DataSet(); try { // Load the customer table from the database into a table called Customers in the dataset mySqlDataAdapter.Fill(myDataSet,"Customers"); // Create a new dataview instance on the Customers table that was just created DataView myDataView = new DataView(myDataSet.Tables["Customers"]); // Sort the view based on the FirstName column myDataView.Sort = "CustomerID"; myDataSet.Tables["Customers"].Rows[0].RowError = "Se ha agregado un error"; myDataSet.Tables["Customers"].Rows[1].RowError = "Otro mensaje de error"; if ( myDataSet.Tables["Customers"].HasErrors ) { DataRow[] ErrDataRows = myDataSet.Tables["Customers"].GetErrors(); Console.WriteLine("DataTable myDataSet.Tables["Customers"].TableName,ErrDataRows.Length.ToString()); for (int i = 0; i <= ErrDataRows.Length -1; i++)

{0}

tiene

{1}

error(es).",

{ Console.WriteLine("Error de fila en la fila {0} -- Mensaje de error={1}",ErrDataRows[i] ["CustomerID"].ToString(),ErrDataRows[i].RowError); } } else { Console.WriteLine("================="); Console.WriteLine("DataTable {0} no tiene errores", myDataSet.Tables["Customers"].TableName); } } catch(Exception e) { Console.WriteLine(e.ToString()); } } } } Trabajar con datos relacionales Un objeto DataSet puede contener tablas no relacionadas o tablas relacionadas. Se puede considerar que un objeto DataSet es un documento de datos. De hecho, los documentos de datos XML son as, con la diferencia de que se basan en un paradigma jerrquico. Como los datos se suelen almacenar en bases de datos relacionales, el objeto DataSet puede controlar relaciones jerrquicas y las relaciones de clave y clave externa. Las relaciones tambin pueden tener distintos tipos de obligatoriedad. De forma predeterminada, las eliminaciones y actualizaciones se aplican en cascada: si se elimina una fila de Customer, tambin se eliminarn las filas relacionadas de Orders; si se actualiza la clave de una fila Customer, tambin se actualizarn los valores de clave externa asociados de la tabla Orders. Un objeto DataSet contiene una coleccin Relations. Es posible agregar una relacin a esta coleccin mediante la columna (o las columnas, si la clave es de varias columnas) de las tablas relacionadas. En el siguiente ejemplo se crea una relacin entre Customers y Orders y se asigna a la relacin el nombre CustOrders. myDataSet.Relations.Add("CustOrders",myDataSet.Tables["Customers"].Columns["CustomerID"], myDataSet.Tables["Orders"].Columns["CustomerID"]); Despus de agregar una relacin entre la clave CustomerID de la tabla Customers y la clave externa CustomerID de la tabla Orders del objeto DataSet, se pueden recorrer los datos. foreach (DataRow myDataRow1 in myDataSet.Tables["Customers"].Rows) { Console.WriteLine("Customer: " + myDataRow1["ContactName"].ToString()); // Iterate over orders data. foreach (DataRow myDataRow2 in myDataRow1.GetChildRows(myDataSet.Relations["CustOrders"])) { Console.WriteLine("Order #" + myDataRow2["OrderID"].ToString()); } Console.WriteLine(); } En el siguiente ejemplo se recorren los datos y se muestran de forma jerrquica en una pgina Web. namespace HowTo.Samples.ADONET { using System; using System.Data; using System.Data.SqlClient; public class relationaldata { public static void Main() { relationaldata myrelationaldata = new relationaldata(); myrelationaldata.Run(); } public void Run() { DataSet myDataSet = new DataSet();

SqlConnection myConnection = new SqlConnection("server= (local)\\NetSDK;Trusted_Connection=yes;database=northwind"); SqlDataAdapter mySqlDataAdapter1 = new SqlDataAdapter("select * from customers", myConnection); SqlDataAdapter mySqlDataAdapter2 = new SqlDataAdapter("select * from orders", myConnection); try { mySqlDataAdapter1.Fill(myDataSet,"Customers"); mySqlDataAdapter2.Fill(myDataSet,"Orders"); // ADD RELATION myDataSet.Relations.Add("CustOrders",myDataSet.Tables["Customers"].Columns["CustomerId"],myDataSet.Tables ["Orders"].Columns["CustomerId"]); // Iterate over data of Customers and their orders foreach (DataRow myDataRow1 in myDataSet.Tables["Customers"].Rows) { Console.WriteLine("Cliente: " + myDataRow1["ContactName"].ToString()); // Iterate over orders data. foreach (DataRow myDataRow2 in myDataRow1.GetChildRows(myDataSet.Relations["CustOrders"])) { Console.WriteLine("Nmero de pedido " + myDataRow2["OrderId"].ToString()); } } Console.WriteLine();

} } }

} catch(Exception e) { Console.WriteLine(e.ToString()); }

Trabajar con datos con tipo La tecnologa ADO tradicional proporciona acceso en tiempo de ejecucin a valores de un conjunto de registros mediante variables con uso no estricto de tipos. El cdigo de ADO.NET permite obtener acceso a los datos contenidos en el objeto DataSet mediante una metfora con "tipos estrictos". Esto significa que se puede obtener acceso a tablas y columnas que forman parte del objeto DataSet con nombres descriptivos y variables con tipos estrictos. Por tanto, en lugar de escribir el cdigo ADO tradicional que se muestra a continuacin: AdoRecordset.Find("CustomerID = 'ALFKI'"); AdoRecordSet.Fields["FirstName"].Value = "Bob";

con un objeto DataSet con tipos estrictos, se puede escribir el siguiente cdigo ADO.NET:

CustomerDataSet.Customers["ALFKI"].CustomerName = "Bob";

Adems, el conjunto de datos con tipos estrictos proporciona acceso a valores de fila como los valores correctos con el tipo estricto. En ADO se utilizan tipos Variant al asignar y recuperar datos. Si el valor asignado es del tipo incorrecto, ADO producira un error en tiempo de ejecucin. En ADO.NET, si el valor es de tipo entero y se intenta asignar una cadena, se producir un error en tiempo de compilacin. Dado un esquema XML compatible con el estndar XSD, es posible generar un conjunto de datos con tipos estrictos mediante la herramienta XSD.exe proporcionada con el SDK de .NET Framework. La sintaxis para generar un conjunto de datos mediante esta herramienta es: xsd.exe /d /l:CS {XSDSchemaFileName.xsd} La directiva /d dirige la herramienta para generar un conjunto de datos; la directiva /l: especifica el lenguaje que se debe utilizar ("C#" o "VB").

En el siguiente ejemplo se utiliza un conjunto de datos con tipos estrictos denominado "myCustDS" para cargar una lista de clientes desde la base de datos Northwind. Cuando se hayan cargado los datos mediante el mtodo Fill, el cdigo recorrer cada cliente de la tabla "Customers" mediante el objeto myDataRow con tipo. Hay que tener en cuenta que se utiliza acceso directo al campo "CustomerID" en lugar de la coleccin Fields. Antes de ejecutar el siguiente ejemplo hay que ejecutar "nmake /a" en el directorio "..\typeddata\DllSrc" desde una ventana de consola para crear el archivo TypedData.dll.

namespace HowTo.Samples.ADONET { using using using using System; System.Data; System.Data.SqlClient; customerDataSet;

public class typeddata { public static void Main() { typeddata mytypeddata = new typeddata(); mytypeddata.Run(); } public void Run() { SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("Select * from customers", "server=(local)\\NetSDK;Trusted_Connection=yes;database=northwind"); try { custDS myCustDS = new custDS(); mySqlDataAdapter.Fill(myCustDS, "Customers"); Console.WriteLine("CustomerID\n"); foreach (custDS.customersRow myDataRow in myCustDS.customers) Console.WriteLine(myDataRow.CustomerID);

} catch(Exception e) { Console.Write(e.ToString()); } } } Filtrar datos }

Existen muchas formas de filtrar datos. Una forma consiste en filtrar datos en el nivel de comandos de base de datos, mediante una clusula en la consulta. Otra forma consiste en filtrar los datos cuando ya estn en el objeto DataSet. En este tema se explica el filtrado en el objeto DataSet. Cuando los datos ya estn en un objeto DataSet, se pueden utilizar mtodos del objeto DataSet para manipular subconjuntos de datos.

Filtrar con el mtodo Select


Considere un objeto DataSet con las tablas Customers y Orders. Para filtrar datos de la tabla Customers que tengan Kelly como valor de FirstName, se puede utilizar el mtodo Select, que devuelve una matriz de filas. myRowArray = dsCustomers.Select("ContactName like 'Kelly%'");

Observe que las instrucciones son del tipo ANSI-SQL. Dichas instrucciones son bsicamente un subconjunto de ANSISQL, con esta diferencia: dado que DataSet puede contener mltiples tablas relacionadas, el filtro tambin puede aplicarse sobre estas tablas relacionadas. En el ejemplo siguiente, utilice la palabra clave Child para filtrar las solicitudes y los clientes. myRowArray = dsCustomers.Select("ContactName like 'Kelly%' AND [child].OrderDate = '7/26/68'");

Estas funciones devuelven una matriz de filas. Puede iterar en la matriz utilizando la instruccin foreach.

Filtrar y ordenar con objetos DataView


Con el objeto DataView, puede colocar mltiples filtros en DataSet, configurar el enlace de datos a ellos, etc. Un objeto DataView se puede filtrar utilizando las mismas reglas de lenguaje que en Select pero, en este caso, el filtro es dinmico. Por tanto, si se agrega una fila a los datos y cumple los criterios del filtro, aparecer en la vista. Las vistas se pueden ordenar y filtrar. Los filtros pueden ser de datos y de versin (actual, nueva, modificada, eliminada). Para configurar un objeto DataView, constryalo de forma que controle a DataTable dentro de DataSet: DataView myDataView = new DataView(myDataSet.Tables["Customers"]); Es posible configurar un filtro con la propiedad RowFilter mediante el mismo lenguaje de filtro de consultas que el del ejemplo del mtodo Select anterior. Para configurar una ordenacin, utilice una lista delimitada por comas de ordenaciones de columnas, seguida de ASC (configuracin predeterminada y opcional) o DESC, con el fin de indicar orden ascendente o descendente. // Sort the view based on the FirstName column myDataView.Sort = "CustomerID"; // Filter the dataview to only show customers with the CustomerID of ALFKI myDataView.RowFilter = "CustomerID='ALFKI'";

Tambin puede filtrar en funcin del estado de las filas (eliminadas, nuevas, etc.). A continuacin se muestra un ejemplo de filtro en filas eliminadas: myDataView.RowStateFilter = DataViewRowState.Deleted; En el siguiente ejemplo se muestra el llenado de un objeto DataSet y el posterior filtrado con un objeto DataView. Hay que tener en cuenta que es fcil enlazar un objeto DataView a datos. Vea los temas de enlace de datos en formularios de Windows o ASP.NET. namespace HowTo.Samples.ADONET { using System; using System.Data; using System.Data.SqlClient; public class filterdatatable { public static void Main() { filterdatatable myfilterdatatable = new filterdatatable(); myfilterdatatable.Run(); } public void Run() { // Create a new Connection and SqlDataAdapter SqlConnection myConnection = SqlConnection("server=(local)\\NetSDK;Trusted_Connection=yes;database=northwind"); SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("select * from customers", myConnection); try { // Create the new instance of the DataSet DataSet myDataSet = new DataSet(); // Load the customer table from the database into a table called Customers in the dataset mySqlDataAdapter.Fill(myDataSet,"Customers"); // Create a new dataview instance on the Customers table that was just created DataView myDataView = new DataView(myDataSet.Tables["Customers"]); // Sort the view based on the FirstName column myDataView.Sort = "CustomerID"; new

// Filter the dataview to only show customers with the CustomerID of ALFKI myDataView.RowFilter = "CustomerID='ALFKI'"; for (int i = 0; i < myDataView.Count; i++) { Console.Write(myDataView[i]["CustomerID"].ToString() + " - " + myDataView[i]["CompanyName"].ToString()); } } catch(Exception e) { Console.WriteLine(e.ToString()); }

} } }

Das könnte Ihnen auch gefallen