Download Acceso a Datos con ADO.NET
Document related concepts
Transcript
Acceso a Datos con ADO.NET ADO.NET constituye la interfaz fundamental de las aplicaciones para proporcionar servicios de acceso a datos en la plataforma Microsoft .NET, donde existen, básicamente, dos elementos: El conjunto de datos desconectado: permiten al usuario trabajar con los datos de una forma desconectada (System.Data.DataSet). La representación interna de los datos del DataSet utiliza XML, por lo que el flujo de datos transferido es independiente de lenguaje y plataforma. Unos proveedores que facilitan la ejecución de operaciones contra un sistema RDBMS. Actualmente están disponibles en .NET Framework: - Proveedor de datos de .NET Framework para SQL Server - Proveedor de datos de .NET Framework para OLE DB - Proveedor de datos de .NET Framework para ODBC - Proveedor de datos de .NET Framework para Oracle Esquema de funcionamiento básico: se utiliza uno de los adaptadores para conectar con el RDBMS recuperando un conjunto de datos y cerrando la conexión. Ese conjunto, que sería un objeto DataSet, puede ser transferido entre aplicaciones y puede operarse sobre él como si fuera una base de datos. Por último, se restablece la conexión usando el proveedor anterior y enviando al RDBMS las actualizaciones realizadas. Objetivos de Diseño Soportar el modelo de programación multinivel (n-tier): en este modelo, los datos se leen de la fuente de datos, se desconecta y pasan a través de los diferentes niveles. Integrar el estándar XML: se pueden transformar los datos a XML, pero también se puede controlar el esquema y leer y escribir en XML. Combinar el paradigma relacional con el orientado a objetos: se provee una interfaz orientada a objetos de los datos a través del tipo DataSet. Reducir los errores de programación: esto se consigue simplificando el modo en el que se accede a los datos. Se puede acceder a los datos de dos formas: leyendo todos los datos del resultado de la consulta y almacenándolos en un DataSet, o leerlos poco a poco a través de un objeto DataReader. Esto lleva a una pérdida de funcionalidad, pero se evita su uso incorrecto o inadvertido. Características ADO.NET no depende de conexiones continuamente activas. Las aplicaciones se conectan a la base de datos sólo durante el tiempo necesario para extraer o actualizar los datos. La base de datos ya no contiene conexiones que la mayor parte del tiempo permanecen inactivas, así que puede dar servicio a muchos más usuarios. Las interacciones con la base de datos se realizan mediante comandos de datos. Para efectuar operaciones en una base de datos, se ejecutan instrucciones SQL o procedimientos almacenados (que incluyen instrucciones SQL). En ADO.NET los comandos de datos se usan para empaquetar las instrucciones SQL o los procedimientos almacenados. Por ejemplo, si se desea leer un conjunto de filas de una base de datos, se crea un comando de datos y se configura con el texto de una instrucción SQL Select o con el nombre del procedimiento almacenado que recupera registros. Los datos se pueden almacenar en memoria caché en conjuntos de datos (DataSet) Ya que sólo son contenedores; se llenan con comandos SQL o procedimientos almacenados que se ejecutan desde un adaptador de datos. Los conjuntos de datos son independientes de los orígenes de datos Dado que un conjunto de datos no está sujeto directamente a un origen de datos, resulta un buen punto de integración para datos procedentes de múltiples orígenes. Los datos se conservan como XML Los datos deben moverse desde el almacén de datos hasta el conjunto de datos y de ahí a diversos componentes. En ADO.NET, el formato de transferencia de datos es XML. En consecuencia, si es necesario conservar datos (por ejemplo, en un archivo), se almacenarán como XML. Si se tiene un archivo XML, se puede utilizar como cualquier otro origen de datos y crear un conjunto de datos a partir de él. No es necesario saber XML para utilizar datos en ADO.NET, ya que convierte automáticamente los datos a XML y viceversa según sea preciso; así que se interactúa con los datos utilizando métodos de programación ordinarios. Las estructuras de datos están definidas por esquemas Los conjuntos de datos se representan como XML. La estructura del conjunto de datos, es decir, la definición de las tablas, columnas, tipos de datos, restricciones, etc. que se encuentran en el conjunto de datos, se define por medio de un esquema XML basado en el lenguaje de definición de esquemas XML (XSD). Los esquemas pueden ser generados y actualizados por Visual Studio .NET según sea necesario, o manualmente. Arquitectura La siguiente ilustración muestra los componentes principales de una aplicación ADO.NET: DataSets Proveedores administrados Figura 1.- Componentes ADO.NET 1 Los componentes de ADO.NET están diseñados para separar el acceso a datos de la manipulación de datos. ADO.NET tiene dos componentes principales que cumplen esta función: el DataSet y el proveedor de datos de .NET Framework, que es un conjunto de componentes entre los que se incluyen los objetos: Connection Command DataReader DataAdapter. En el siguiente diagrama se ilustran los componentes de la arquitectura de ADO.NET. Figura 2.- Arquitectura de ADO.NET Para poder utilizar ADO.NET es necesario incluir el espacio de nombres System.Data, para ellos basta con introducir en la aplicación la directiva: using System.Data 1 BIZTALK.- BizTalk Server 2004 es un producto de Windows Server System que permite a los clientes integrar sistemas, empleados y asociados comerciales con más eficacia y rapidez que nunca. Conjuntos de Datos Un conjunto de datos es una memoria caché desconectada de registros recuperados de un origen de datos. Funciona como un almacén virtual de datos: un conjunto de datos incluye una o más tablas basadas en las tablas de la base de datos real y puede incluir información acerca de las relaciones entre estas tablas y las restricciones para los datos que puede contener cada tabla. Los datos del conjunto de datos suelen ser una versión muy reducida de lo que hay en la base de datos. Sin embargo, puede trabajar con ellos igual que lo hace con los datos reales. Mientras se esté trabajando, se permanecerá desconectado de la base de datos, que quedará libre para ejecutar otras tareas. El conjunto de datos es un contenedor pasivo para los datos. Para extraer realmente datos de la base de datos y (opcionalmente) escribirlos de nuevo, se utilizan adaptadores de datos. Un adaptador de datos contiene uno o varios comandos utilizados para llenar una única tabla del conjunto de datos y para actualizar la tabla correspondiente de la base de datos. Como el conjunto de datos es realmente una copia privada de los datos de la base de datos, no reflejará necesariamente el estado actual de la base de datos, para ver los últimos cambios realizados por otros usuarios, se puede actualizar el conjunto de datos; llamando al método Fill correspondiente. Una de las ventajas de utilizar conjuntos de datos es que los componentes pueden intercambiarlos cuando lo necesiten. Por ejemplo, un objeto podría crear y llenar un conjunto de datos y, a continuación, enviarlo a otro componente en otro punto de la aplicación para que lo procese. Esta facilidad significa que los componentes no necesitan consultar la base de datos de forma individual. Un conjunto de datos de ADO.NET es una vista relacional de los datos que se pueden representar en XML. Espacio de nombres de conjunto de datos: Figura 3.- Espacio de nombres de Conjuntos de Datos Los métodos y objetos contenidos en un DataSet son coherentes con los del modelo de base de datos relacional. La DataTableCollection Un DataSet de ADO.NET contiene una colección de cero o más tablas representadas por objetos DataTable. La DataTableCollection contiene todos los objetos DataTable de un DataSet. Un DataTable se define en el espacio de nombres System.Data y representa una única tabla de datos residentes en memoria. Contiene una colección de columnas representadas por una DataColumnCollection y restricciones representadas por una ConstraintCollection que, juntas, definen el esquema de la tabla. Un DataTable también contiene una colección de filas representadas por la DataRowCollection, que contiene los datos de la tabla. Junto con su estado actual, un DataRow conserva tanto la versión original como la actual para identificar los cambios realizados en los valores almacenados en la fila. La DataRelationCollection Un DataSet contiene relaciones en su objeto DataRelationCollection. Una relación, representada por el objeto DataRelation, asocia las filas de un DataTable con las filas de otro DataTable. Es análogo a una ruta de unión que podría existir entre las columnas de claves externas y principales en una base de datos relacional. Un DataRelation identifica columnas coincidentes en dos tablas de un DataSet. Las relaciones permiten pasar de una tabla a otra dentro de un mismo DataSet. Los elementos esenciales de un DataRelation son el nombre de la relación, el nombre de las tablas relacionadas y las columnas relacionadas de cada tabla. Se pueden establecer relaciones con más de una columna por tabla, para lo que debe especificar una selección de objetos DataColumn como columnas clave. Cuando se agrega una relación al DataRelationCollection, se puede agregar también un UniqueKeyConstraint y un ForeignKeyConstraint para imponer restricciones de integridad cuando se realicen cambios en los valores de las columnas relacionadas. ExtendedProperties El DataSet (así como el DataTable y el DataColumn) tiene una propiedad ExtendedProperties. ExtendedProperties es un PropertyCollection en el que se puede colocar información personalizada, como la instrucción SELECT que sirve para generar el conjunto de resultados, o una marca de fecha y hora de cuándo se generaron los datos. La colección ExtendedProperties se conserva con la información del esquema del DataSet (así como el DataTable y el DataColumn). Clasificación Los conjuntos de datos pueden tener tipo o no. Un conjunto de datos con tipo se deriva en primer lugar de la clase base DataSet y, a continuación, utiliza la información de un archivo de esquema XML (archivo .xsd) para generar una clase nueva. La información del esquema (tablas, columnas, etc.) se genera y compila en esta nueva clase de conjunto de datos como un conjunto de objetos y propiedades de primera clase. Dado que una clase DataSet con tipo hereda de la clase base DataSet, la clase con tipo asume toda la funcionalidad de la clase DataSet y puede utilizarse con métodos que toman como parámetro una instancia de una clase DataSet. Por el contrario, un conjunto de datos sin tipo no tiene el esquema integrado correspondiente. Al igual que un conjunto de datos con tipo, un conjunto de datos sin tipo contiene tablas, columnas, etc., pero sólo se exponen como colecciones. No obstante, después de crear manualmente las tablas y otros elementos de datos de un conjunto de datos sin tipo, se puede exportar la estructura del conjunto de datos en forma de esquema por medio del método WriteXmlSchema del conjunto de datos. Proveedores Datos El otro elemento central de la arquitectura de ADO.NET es el proveedor de datos de .NET Framework, cuyos componentes están diseñados expresamente para la manipulación de datos y para el acceso rápido a datos de avance de sólo lectura. Es posible escribir proveedores de datos de .NET Framework para cualquier origen de datos. Tipos proveedores de datos incluidos en .NET Framework Proveedor de datos de .NET Framework para SQL Server. El proveedor de datos de .NET Framework para SQL Server utiliza su propio protocolo para establecer comunicaciones con SQL Server. Necesita incluir el espacio de nombres System.Data.SqlClient Proveedor de datos de .NET Framework para OLE DB. Para utilizar este proveedor se debe usar un proveedor OLE DB compatible. Proveedores que se han probado con ADO.NET. Controlador SQLOLEDB MSDAORA Microsoft.Jet.OLEDB.4.0 Proveedor Proveedor OLE DB para SQL Server de Microsoft Proveedor OLE DB para Oracle de Microsoft Proveedor OLE DB para Microsoft Jet Necesita incluir el espacio de nombres System.Data.OleDb. Proveedor de datos de .NET Framework para ODBC. El proveedor de datos ODBC .NET está pensado para funcionar con todos los controladores que cumplan las especificaciones ODBC. Necesita incluir el espacio de nombres System.Data.Odbc. Proveedor de datos de .NET Framework para Oracle. El proveedor de datos es compatible con la versión 8.1.7 y posteriores del software de cliente de Oracle. Necesita incluir el espacio de nombres System.Data.OracleClient. Objetos DataAdapter El objeto xDataAdapter 2 representa un conjunto de comandos de datos y una conexión a base de datos que se utilizan para rellenar el conjunto de datos DataSet y actualizar el origen de datos proporcionando el puente entre el objeto DataSet y el origen de datos. El DataAdapter utiliza objetos xCommand para ejecutar comandos SQL en el origen de datos tanto para cargar el DataSet con datos como para actualizar el origen de datos con los cambios aplicados a los datos incluidos en el DataSet. Generalmente, cada adaptador de datos intercambia datos entre una sola tabla de un origen de datos y un solo objeto DataTable del conjunto de datos. Si el conjunto de datos contiene varias tablas de datos, la estrategia habitual consiste en tener varios adaptadores de datos que le suministren datos y los escriban de nuevo en tablas individuales del origen de datos. Para llenar una tabla de un conjunto de datos, se llama a un método adaptador que ejecute una instrucción SQL o un procedimiento almacenado. El adaptador crea un objeto lector de datos (xDataReader) para leer los datos de un conjunto de datos. Existe la opción de leer datos de la base de datos sin tener que almacenarlos en un conjunto de datos, lo que puede ser muy eficiente en situaciones en las que estén implicados datos de sólo lectura, así como se pueden ejecutar instrucciones SQL directamente, sin utilizarlas para llenar un conjunto de datos. De forma similar, cuando se desee actualizar la base de datos, se deberá invocar un método adaptador que llame a la instrucción SQL o el procedimiento almacenado adecuados para realizar la actualización real en la base de datos. Propiedades importantes: - SelectCommand – referencia a un comando (instrucción SQL o nombre de procedimiento almacenado) que recupera filas del almacén de datos. - InsertCommand – referencia a un comando para insertar filas en un almacén de datos. - UpdateCommand – referencia a un comando para modificar filas en el almacén de datos. - DeleteCommand – referencia a un comando para eliminar filas del almacén de datos. - TableMappings -- Los nombres de la base de datos y del conjunto de datos no tienen por qué coincidir. Se pueden crear nuevos nombres de tabla y columna en el comando del conjunto de datos y, a continuación, asignarlos a los nombres que se utilizan en la base de datos. Los adaptadores utilizan la colección TableMappings para mantener la correspondencia entre las estructuras del conjunto de datos (tablas de datos y columnas de datos) y las estructuras del almacén de datos (tablas y columnas). Objetos Connection El objeto xConnection proporciona conectividad con un origen de datos. 2 Dependiendo del proveedor de datos utilizado, sustitúyase “x” por: Sql, OleDb, Odbc, OrecleClient o el que corresponda. Un adaptador de datos necesita una conexión abierta con un origen de datos para leer y escribir datos. Por tanto, un adaptador utiliza objetos Connection para comunicarse con un origen de datos. El adaptador puede contener como máximo cuatro referencias de conexión, una para cada tipo de acción que puede ejecutar: seleccionar, actualizar, insertar y eliminar (asociadas a sus propiedades). El objeto Connection representa una sesión única dentro del origen de datos. Todos los objetos de conexión proporcionan propiedades para establecer y modificar los detalles de la conexión (como el identificador de usuario, la contraseña y el tiempo de espera). También proporcionan métodos para iniciar, confirmar y deshacer transacciones de base de datos. Se recomienda cerrar siempre el objeto Connection al terminar de utilizarlo para que la conexión se devuelva a la agrupación. Esta operación se puede realizar mediante los métodos Close o Dispose del objeto Connection. Objetos DataReader xDataReader proporciona una secuencia de datos de alto rendimiento, de sólo lectura y sólo hacia delante, a partir de un origen de datos. Siempre se debe llamar al método Close cuando haya terminado de usar el objeto DataReader. Si Command contiene parámetros de salida o valores devueltos, éstos no estarán disponibles hasta que se cierre el DataReader. Mientras está abierto un DataReader, éste usa de forma exclusiva el objeto Connection. Por eso no podrá ejecutar ningún comando en el objeto Connection, ni siquiera el de creación de otro DataReader, hasta que se cierre el DataReader original. A la hora de decidir si una aplicación debe utilizar un DataReader o un DataSet se debe tener en cuenta el tipo de funcionalidad que la aplicación requiere. Se usará un DataSet para: Utilizar datos de forma remota entre un nivel y otro o desde un servicio Web XML. Interactuar con datos dinámicamente, por ejemplo para enlazar con un control de Windows Forms o para combinar y relacionar datos procedentes de varios orígenes. Almacenar datos en memoria caché localmente, dentro de su aplicación. Proporcionar una vista XML jerárquica de datos relacionales y utilizar herramientas como una transformación XSL o una consulta Xpath (XML Path Language) en sus datos. Realizar procesamientos exhaustivos de datos sin necesidad de tener una conexión abierta con el origen de datos, lo que libera la conexión para que la utilicen otros clientes. Si no se necesita la funcionalidad proporcionada por el DataSet, se puede mejorar el rendimiento de la aplicación si se utiliza DataReader para devolver los datos de sólo avance y de sólo lectura. Aunque el DataAdapter usa el DataReader para rellenar el contenido de un DataSet, al utilizar el DataReader se puede mejorar el rendimiento porque no usará la memoria que utilizaría el DataSet, además de evitar el procesamiento necesario para crear y rellenar el contenido del DataSet. Objetos Command El objeto xCommand representa una instrucción SQL o un procedimiento almacenado que ejecutar en un origen de datos, por lo que permite tener acceso a comandos de base de datos para devolver datos, modificar datos, ejecutar procedimientos almacenados y enviar o recuperar información sobre parámetros. El objeto Command posee varios métodos Execute: ExecuteReader Cuando los resultados se devuelven en forma de secuencia de datos, se usa para devolver un objeto DataReader. ExecuteNonQuery Se utiliza para ejecutar comandos que no devuelven filas (realizar operaciones en la base de datos y modificar datos). Mediante un proveedor de datos de .NET Framework se puede ejecutar procedimientos almacenados o instrucciones de DDL (CREATE TABLE…) para manipular los esquemas de una base de datos o catálogo. El objeto Command proporciona un método ExecuteNonQuery para procesarlos. Además de para modificar esquemas, este método se puede usar también para procesar instrucciones SQL que modifican datos sin devolver ninguna fila, como INSERT, UPDATE y DELETE. El método ExecuteNonQuery devuelve un entero que representa el número de filas que se ven afectadas por la instrucción o por el procedimiento almacenado que se haya ejecutado. ExecuteScalar Este método devuelve como valor escalar el correspondiente a la primera columna de la primera fila del conjunto de resultados. Bibliografía [1] Sceppa D. “Microsoft ADO.NET”. MICROSOFT PRESS. [2] Skinner J, et al. “Professional ADO.NET Programming”. WROX PRESS. [3] Riordan R. “Microsoft ADO .NET Step by Step., MICROSOFT PRESS. [4] Chand M. “A Programmer’s Guide to ADO.NET in C#”. APRESS, 2002. [5] Beauchemin B. “Essential ADO.NET“. ADDISON WESLEY. [6] Joubert T. “ADO .NET Programming”. WORDWARE PUBLISHING. [7] Hamilton B. “ADO.NET Cookbook”. O’REILLY, 2003.