Professional Documents
Culture Documents
ADO.NET
Índice
Descripción 1
Lección: introducción al uso de ADO.NET 2
Lección: conectar a una base de datos 6
Lección: acceso a datos con DataSets 14
Lección: utilizar múltiples tablas 34
Lección: acceder a datos con DataReaders 44
Acceso a datos con Microsoft ADO.NET 1
Descripción
Introducción a ADO.NET
Conectar a una base de datos
Acceder a datos con DataSets
Utilizar múltiples tablas
Acceder a datos con DataReaders
*****************************
Introducción Crear un sitio Web dinámico que responda a las peticiones de los usuarios con
datos personalizados puede requerir que vinculemos nuestra aplicación Web a
varias fuentes de datos. Microsoft® ADO.NET es la herramienta que nos
permite acceder programáticamente a fuentes de datos desde un formulario
Web Form.
En este módulo, aprenderemos a utilizar ADO.NET para agregar acceso a datos
a nuestra aplicación Web con Microsoft ASP.NET.
Objetivos de la lección En esta lección, aprenderemos a:
Describir el modelo de objetos de ADO.NET para acceder a datos.
Crear conexiones seguras a una base de datos Microsoft SQL Server™
utilizando los objetos SqlConnection y SqlDataAdapter.
Utilizar objetos DataSet para soportar los requerimientos de
almacenamiento y manipulación de datos locales de los formularios Web
Forms.
Almacenar múltiples tablas de datos en un objeto DataSet, y mostrar los
datos en controles DataGrid.
Leer datos programáticamente de una base de datos SQL utilizando un
objeto SqlDataReader.
2 Acceso a datos con Microsoft ADO.NET
*****************************
Introducción ADO.NET está diseñado para cargar datos desde una fuente de datos y trabajar
con esos datos en modo desconectado. Este estado de desconexión permite al
formulario Web Form operar de forma semi-independiente de las fuentes de
datos, reduciendo así el tráfico de red. ADO.NET utiliza Extensible Markup
Language (XML) como formato universal de transmisión de datos, lo cual
garantiza la interoperabilidad con cualquier plataforma donde esté disponible
un parser XML.
En esta lección, estudiaremos el uso del modelo de objetos de ADO.NET para
acceder a datos. También estudiaremos cómo utilizar los objetos DataSet y
DataReader para acceder a datos.
Objetivos de la lección En esta lección, aprenderemos a:
Describir el acceso a datos de los objetos DataSet y DataReader.
Escoger entre los objetos DataSet y DataReader, dependiendo de las
necesidades de acceso a datos de una aplicación Web.
Acceso a datos con Microsoft ADO.NET 3
DataSet DataReader
Acceso lectura/escritura a
Sólo lectura
datos
Incluye múltiples tablas de Basado en una instrucción SQL
distintas bases de datos de una base de datos
Desconectado Conectado
Vinculado a múltiples controles Vinculado a un único control
Búsqueda de datos hacia
Sólo hacia delante
delante y hacia atrás
Acceso más lento Acceso más rápido
Soportado por las herramientas
Codificación manual
de Visual Studio .NET
*****************************
Introducción Los objetos DataSet son objetos complejos que nos permiten almacenar
múltiples tablas de datos DataTables desde una fuente de datos. Los objetos
DataSet son como una base de datos virtual ubicada dentro de una aplicación
Web. Los objetos DataSet también pueden contener relaciones entre los datos
de las DataTables, y pueden utilizar esas relaciones para recuperar datos.
Los objetos DataReader son objetos ligeros que se utilizan para leer datos
desde una fuente de datos; los objetos DataReader proporcionan acceso sólo
hacia delante (forward-only) y de sólo lectura (read-only) a los datos de una
base de datos.
Uso de DataSets y La elección entre utilizar objetos DataSet u objetos DataReader debería
DataReaders basarse en el uso previsto para los datos. Normalmente, los objetos
DataReader se utilizan para leer datos en situaciones en las que es necesario el
acceso una única vez, y de solo lectura, como cuando accedemos a una
contraseña almacenada, o se cumplimenta un control enlazado a una lista. Los
objetos DataSet se utilizan para un acceso a datos más complejo, como el
acceso a todo el historial de pedidos de un cliente.
Algunos de los aspectos relativos al acceso a datos que se deben tener en cuenta
a la hora de decidir entre objetos DataSet y DataReader incluyen:
Acceso a datos
Si nuestra intención es leer y escribir a nuestra fuente de datos, debemos
utilizar un objeto DataSet. Los objetos DataReader son conexiones de sólo
lectura y deberían utilizarse únicamente cuando los datos vayan a utilizarse
en una situación de sólo lectura.
Acceso a múltiples bases de datos
Si nuestra intención es combinar tablas de una o más bases de datos,
debemos utilizar un objeto DataSet. Los objetos DataReader se basan en
una única instrucción SQL de una sola base de datos.
Enlace a controles
4 Acceso a datos con Microsoft ADO.NET
Los estudiantes:
z Seleccionarán la mejor opción de acceso
a datos para determinados escenarios
Tiempo: 5 minutos
*****************************
____________________________________________________________
____________________________________________________________
____________________________________________________________
____________________________________________________________
6 Acceso a datos con Microsoft ADO.NET
*****************************
Introducción El primer paso en el uso de una base de datos para soportar nuestra aplicación
Web es crear una conexión segura a la base de datos. Las conexiones no
seguras pueden exponer a ataques mal intencionados tanto la aplicación Web
como la base de datos.
En esta lección, aprenderemos a crear conexiones seguras a una base de datos
SQL Server utilizando los objetos SqlConnection y SqlDataAdapter.
Objetivos de la lección En esta lección, aprenderemos a:
Explicar la diferencia entre el modo mixto y la autenticación sólo Windows.
Crear una conexión, con autenticación sólo Windows, a una base de datos
SQL Server.
Acceso a datos con Microsoft ADO.NET 7
o… No enviar el nombre de
o…
usuario y contraseña.
Enviar sólo que el
Cliente
Cliente usuario ha sido
Autenticación
Autenticación autenticado.
sólo
sóloWindows
Windows
Servidor
ServidorSQL
SQL
Servidor Sólo
Sólolalacuenta
cuentaASPNET
ASPNET
ServidorWeb
Web tiene
Autenticación
AutenticaciónWindows
Windows tieneconcedido
concedidoacceso
acceso
*****************************
Introducción Desde la perspectiva del usuario, el acceso a datos desde una base de datos SQL
Server es un proceso en dos pasos. En primer lugar, el usuario envía una
petición a la aplicación Web, y ésta se conecta a la base de datos SQL Server
para satisfacer la solicitud. Existen dos métodos principales para que una
aplicación Web se conecte a una base de datos SQL Server: autenticación en
modo mixto y autenticación en modo sólo Windows. El método más utilizado
es la autenticación sólo Windows.
Autenticación En modo La autenticación en modo mixto utiliza la configuración predeterminada de
mixto ASP.NET y de la aplicación Web. Cada usuario de la aplicación Web debe
tener una cuenta de usuario añadida al grupo logins de SQL Server. El punto
débil de la autenticación en modo mixto es que los nombres de usuario y las
contraseñas se envían al equipo que ejecuta SQL Server en código HTML no
encriptado. Estos datos expuestos podrían permitir a terceros obtener las
credenciales de inicio de sesión. Además, es necesario administrar cuentas de
usuario tanto en el servidor Web como en el equipo que ejecuta SQL Server.
Para utilizar la autenticación en modo mixto, configurar SQL Server en modo
de autenticación mixto (SQL Server y Windows). El siguiente código puede
utilizarse para conectar a un SQL Server con autenticación en modo mixto:
Visual Basic .NET Dim strConn As String = _
"data source=localhost; " & _
"initial catalog=northwind; " & _
"user id=CohoUser;password=1Coho"
Dim conn As New SqlConnection(strConn)
C# string strConn =
"data source=localhost; " +
"initial catalog=northwind; " +
"user id=CohoUser; " +
"password=1Coho";
SqlConnection conn = new SqlConnection(strConn);
8 Acceso a datos con Microsoft ADO.NET
Autenticación sólo La autenticación en modo sólo Windows es el método más utilizado para
Windows conectar una aplicación Web a una base de datos SQL Server. Cuando
utilizamos la autenticación en modo sólo Windows, SQL Server no necesita el
nombre de usuario y la contraseña. Sólo se requiere una confirmación de que el
usuario ha sido autenticado por una fuente de confianza para procesar la
petición a la base de datos.
El proceso de la autenticación en modo sólo Windows utiliza una sola cuenta
denominada ASPNET para todos los accesos a SQL Server desde la aplicación
Web. Esta única cuenta elimina los problemas de transmitir nombres de usuario
y contraseñas no encriptados entre la aplicación Web y SQL Server, junto con
la necesidad de mantener cuentas de usuario en ambos servidores.
Con la autenticación en modo sólo Windows, los usuarios acceden al
formulario Web Form como usuarios anónimos. ASP.NET se conecta a SQL
Server y se autentica utilizando la cuenta de usuario ASPNET. Los datos
solicitados son devueltos por SQL Server y utilizados por la aplicación Web.
Finalmente, el formulario Web Form que incluye los datos solicitados se
devuelven al usuario.
Para utilizar la autenticación en modo sólo Windows, configuramos SQL
Server con la autenticación en modo sólo Windows. El siguiente código puede
utilizarse para conectar a un SQL Server con autenticación en modo sólo
Windows:
Visual Basic .NET Dim strConn As String = _
"data source=localhost; " & _
"initial catalog=northwind; " & _
"integrated security=true"
Dim conn As New SqlConnection(strConn)
C# string strConn =
"data source=localhost; " +
"initial catalog=northwind; " +
"integrated security=true";
SqlConnection conn = new SqlConnection(strConn);
Acceso a datos con Microsoft ADO.NET 9
Configurar el SQL Cuando utilizamos la autenticación en modo sólo Windows, podemos mantener
Server para ejecutar a SQL Server en el modo de autenticación predeterminado de sólo Windows. Si
autenticación utilizamos la autenticación en modo mixto, necesitamos modificar el modo de
en modo mixto o sólo autenticación de SQL Server.
Windows
Ë Cambiar el modo de autenticación de SQL Server
1. En el menú Inicio, hacer clic con el botón derecho en Mi PC y clic en
Administrar.
2. En la consola Administración de equipos, expandir la carpeta Servicios y
Aplicaciones y la carpeta Servidores Microsoft SQL Server.
3. Hacer clic con el botón derecho en el servidor SQL Server (local) y clic en
Propiedades.
4. En el cuadro de diálogo Propiedades de SQL Server, en la ficha
Seguridad, hacer clic en el botón de opción SQL Server y Windows o la
opción sólo Windows de la sección Autenticación, y hacer clic en
Aceptar.
Nota Para más información sobre securizar una aplicación Web, ver el Módulo
“Securizar una aplicación Web con Microsoft ASP.NET”.
10 Acceso a datos con Microsoft ADO.NET
Crear la conexión
Uso de SqlConnection
Dim
Dim strConn
strConn AsAs String
String == "data
"data source=localhost;
source=localhost; "" && __
"initial
"initial catalog=northwind;
catalog=northwind; integrated
integrated security=true"
security=true"
Dim
Dim conn
conn As
As New
New SqlConnection(strConn)
SqlConnection(strConn)
string
string strConn
strConn == "data
"data source=localhost;
source=localhost; "" ++
"initial
"initial catalog=northwind;
catalog=northwind; integrated
integrated security=true";
security=true";
SqlConnection
SqlConnection conn
conn == new
new SqlConnection(strConn);
SqlConnection(strConn);
Introducción Para mover datos entre una base de datos y nuestra aplicación Web, en primer
lugar debemos crear una conexión a la base de datos. Para ello, debemos
identificar el nombre del servidor de base de datos, el nombre de la base de
datos, y la información de inicio de sesión requerida.
Dependiendo del tipo de base de datos al que accedamos, podemos utilizar un
objeto SqlConnection o un objeto OleDbConnection. Utilizamos un objeto
SqlConnection para conectar a bases de datos SQL Server 7.0 o posterior, y
objetos OleDbConnection para conectar al resto de bases de datos.
Crear una cadena de Creamos un objeto SqlConnection pasando una cadena de conexión que
conexión proporciona los parámetros necesarios para crear una conexión a una fuente de
datos.
El siguiente código de ejemplo crea un objeto SQLConnection a la base de
datos SQL Server Northwind:
Visual Basic .NET Dim strConn As String = _
"data source=localhost; " & _
"initial catalog=northwind; " & _
"integrated security=true"
Dim conn As New SqlConnection(strConn)
C# string strConn =
"data source=localhost; " +
"initial catalog=northwind; " +
"integrated security=true";
SqlConnection conn = new SqlConnection(strConn);
Acceso a datos con Microsoft ADO.NET 11
Parámetros de la cadena La siguiente tabla describe algunos de los parámetros más habituales de un
de conexión objeto de conexión:
Parámetro Descripción
*****************************
*****************************
Introducción El objeto DataSet representa una copia local de los datos que provienen de una
o más fuentes de datos. El uso de un objeto DataSet permite que un formulario
Web Form se ejecute de forma semi-independiente de las fuentes de datos. El
objeto DataSet puede utilizar un objeto DataAdapter para cargar los datos de
una fuente de datos y puede desconectarse de la misma. El usuario puede
entonces utilizar y manipular los datos. Cuando los datos necesitan ser
actualizados contra la fuente de datos, se utiliza un objeto DataAdapter para
volver a conectarse y actualizar la fuente de datos.
En esta lección, estudiaremos cómo utilizar los objetos DataSet para soportar el
almacenamiento local de datos y los requerimientos de manipulación de los
formularios Web Forms.
Objetivos de la lección En esta lección, aprenderemos a:
Crear un objeto DataAdapter para enlazar un objeto DataSet a una fuente
de datos.
Crear un objeto DataSet para guardar datos de una fuente de datos.
Utilizar objetos DataView para guardar un subconjunto de datos de un
objeto DataSet.
Vincular un objeto DataSet y un objeto DataView a un control enlazado a
lista.
Gestionar los errores típicos que nos encontramos en el acceso a datos.
Acceso a datos con Microsoft ADO.NET 15
Crear un DataAdapter
SqlDataAdapter
SqlDataAdapter da
da == new
new SqlDataAdapter
SqlDataAdapter
("select
("select ** from
from Authors",conn);
Authors",conn);
da.SelectCommand.CommandText;
da.SelectCommand.CommandText;
da.SelectCommand.Connection;
da.SelectCommand.Connection;
Introducción El objeto DataSet representa una copia local de datos de una fuente de datos.
Cuando se utiliza sin una fuente de datos, el objeto DataSet resulta útil para
guardar datos locales a los cuales pueden acceder los formularios Web Forms.
Sin embargo, para actuar como una herramienta de gestión de datos real, un
objeto DataSet debe poder interactuar con una o más fuentes de datos. Para
conseguir esta interacción, el .NET Framework proporciona las clases
SqlDataAdapter y OleDbDataAdapter.
DataAdapter Un objeto DataAdapter actúa como enlace entre un objeto DataSet y una
fuente de datos que puede utilizarse para recuperar y guardar datos. La clase
DataAdapter representa un conjunto de comandos de base de datos y una
conexión a una base de datos que utilizamos para rellenar un objeto DataSet y
actualizar la fuente de datos. Cada objeto DataAdapter intercambia datos entre
un único objeto DataTable en un objeto DataSet y un único conjunto de
resultados de una instrucción SQL o un procedimiento almacenado.
Visual Studio .NET pone a disposición dos clases principales DataAdapter
para su uso con bases de datos:
Clase OleDbDataAdapter
Esta clase es adecuada para utilizarse con cualquier fuente de datos expuesta
por un OLE DB Data Provider.
Clase SqlDataAdapter
Esta clase es específica para una base de datos SQL Server versión 7.0 o
posterior. El objeto SqlDataAdapter es más rápido que el objeto
OleDbDataAdapter porque funciona directamente con SQL Server y no
debe funcionar a través de una capa OLE DB Data Provider.
Además, las clases DataAdapter para otros tipos de fuentes de datos pueden
integrarse con Visual Studio .NET.
16 Acceso a datos con Microsoft ADO.NET
Propiedades del Cuando utilizamos objetos DataAdapter para intercambiar datos entre un
DataAdapter objeto DataSet y una fuente de datos, podemos especificar las acciones que
deseamos realizar utilizando una de las cuatro propiedades DataAdapter. Las
propiedades DataAdapter ejecutan una instrucción SQL o invocan un
procedimiento almacenado.
Las propiedades que están disponibles con la clase DataAdapter se muestran
en la siguiente tabla.
Propiedad Función
C# //Create a connection
SqlConnection conn = new SqlConnection
("data source=localhost; initial catalog=pubs; " +
"integrated security=true; persist security info=True;");
Crear un DataSet
Acceder a DataTable
ds.Tables["Authors"].Rows.Count;
ds.Tables["Authors"].Rows.Count; ds.Tables("Authors").Rows.Count
ds.Tables("Authors").Rows.Count
string
string str="";
str=""; Dim
Dim rr As
As DataRow
DataRow
Dim
Dim str
str As
As String
String
foreach(DataRow
foreach(DataRow rr inin For
For Each
Each rr in
in __
ds.Tables["Authors"].Rows)
ds.Tables["Authors"].Rows) ds.Tables("Authors").Rows
ds.Tables("Authors").Rows
{{
str
str &=
&= r(2)
r(2)
str
str +=
+= r[2];
r[2]; str
str &=
&= r("au_lname")
r("au_lname")
str
str +=
+= r["au_lname"];
r["au_lname"]; Next
Next
}}
*****************************
Introducción Para crear una copia local de una base de datos, creamos y poblamos un objeto
DataSet utilizando objetos DataTable.
Crear a DataSet El primer paso para crear un objeto DataSet es declarar el nombre del objeto
DataSet. El siguiente código crea un objeto DataSet denominado ds:
Visual Basic .NET Dim ds As New DataSet()
Rellenar el DataSet Tras crear un objeto DataSet, rellenamos los objetos DataTable creando un
objeto DataAdapter. Invocamos el método Fill en el objeto DataAdapter y
especificamos el objeto DataTable que deseamos rellenar. El siguiente código
rellena la tabla Authors del objeto DataSet ds utilizando un DataAdapter
denominado da:
Visual Basic .NET da.Fill(ds, "Authors")
C# da.Fill(ds, "Authors");
C# //Create a connection
SqlConnection conn = new SqlConnection
("data source=localhost;initial catalog=pubs; " +
"integrated security=SSPI;persist security info=True;");
C# ds.Tables["Authors"];
-o-
ds.Tables[0];
Acceso a datos con Microsoft ADO.NET 19
C# ds.Tables["Authors"].Rows.Count;
ds.Tables["Authors"].Columns.Count;
Contar las filas y columnas del objeto DataTable nos permite acceder a campos
individuales del objeto DataTable. Podemos acceder a campos por posición
ordinal (basada-en-0) o por el nombre. En el siguiente código, x es el índice de
la fila de datos a la que deseamos acceder:
Visual Basic .NET DataSet.Tables(0).Rows(x)(1)
DataSet.Tables(0).Rows(x)("fieldname")
C# ds.Tables["Authors"].Rows[x][1];
ds.Tables["Authors"].Rows[x]["fieldname"];
20 Acceso a datos con Microsoft ADO.NET
*****************************
Ë Ejecutar la demostración
1. Abrir la página UseDataSet.aspx del proyecto Demo08VB o Demo08CS
que se pueden encontrar dentro del fichero demos08.zip.
2. Generar y examinar la página.
La primera vez que se carga la página, el cuadro de lista lstItems se rellena
dinámicamente con los nombres de las columnas del DataSet.
El botón Get Number of Rows y el botón Get Values leen la información
del DataSet.
3. Hacer clic en Get Number of Rows.
El código en el procedimiento de evento click muestra la propiedad Count
de la colección Rows.
4. Seleccionar una columna en el cuadro de lista y hacer clic en Get Values.
El código en el procedimiento de evento click recorre en bucle las filas del
DataSet y muestra el campo seleccionado.
5. En Visual Studio .NET, visualizar la página de código subyacente de la
página UseDataSet.aspx.
22 Acceso a datos con Microsoft ADO.NET
Utilizar un DataView
DataView
DataView dv
dv == ds.Tables["Authors"].DefaultView;
ds.Tables["Authors"].DefaultView;
DataView
DataView dv
dv == new
new DataView(ds.Tables["Authors"]);
DataView(ds.Tables["Authors"]);
dv.RowFilter
dv.RowFilter == "state
"state == 'CA'";
'CA'";
*****************************
Introducción Para mostrar los datos que almacena un objeto DataSet, podemos vincular el
objeto DataSet directamente a un control enlazado a una lista o utilizar un
objeto DataView. Un objeto DataView es una vista personalizada y enlazable
de un único objeto DataTable. Después de crear un objeto DataView, el
usuario puede utilizarlo para clasificar, filtrar, buscar, editar y navegar por
datos.
DataViews como Los objetos DataView pueden personalizarse para presentar un subconjunto de
subconjunto de un datos de un objeto DataTable. Esta personalización permite tener dos controles
DataTable vinculados al mismo objeto DataTable, pero con cada control mostrando
distintas versiones de los datos. Por ejemplo, un control puede estar vinculado a
un objeto DataView mostrando todas las filas de la tabla, y un segundo control
puede estar vinculado a otro objeto DataView configurado para mostrar
únicamente las filas que se han eliminado del objeto DataTable.
DefaultView Cada objeto DataTable de un objeto DataSet tiene una propiedad
DefaultView, que devuelve la vista predeterminada de la tabla. El siguiente
código muestra cómo podemos acceder al objeto DataView dv predeterminado,
de un objeto DataTable denominado Authors:
Visual Basic .NET Dim dv As DataView = ds.Tables("Authors").DefaultView
C# DataView dv = ds.Tables["Authors"].DefaultView;
24 Acceso a datos con Microsoft ADO.NET
Los estudiantes:
z Reordenarán líneas de código para crear
un DataSet
Tiempo: 5 minutos
*****************************
Ë Ejecutar la práctica
• Visualizar la página http://localhost/Mod10VB/DataSetCode.aspx o
http://localhost/Mod10CS/DataSetCode.aspx y organizar las líneas de
código ADO.NET en el orden correcto para crear un objeto DataSet.
Crear el control
<asp:DataGrid
<asp:DataGrid id="dg"
id="dg" runat="server"
runat="server" />
/>
*****************************
Vincular a un Dataset o Para vincular un objeto DataSet a un control DataGrid, en primer lugar
DataView debemos establecer la propiedad DataSource del control DataGrid a un objeto
DataSet, DataTable o DataView, e invocar el método DataBind.
Si establecemos la propiedad DataSource del control DataGrid directamente a
un objeto DataSet, el objeto DataTable con el índice 0 se utiliza de forma
predeterminada. Para especificar otro objeto DataTable, establecer la
propiedad DataMember del control DataGrid con el nombre del objeto
DataTable deseado.
El siguiente código de ejemplo muestra cómo vincular la tabla Authors, del
objeto DataSet ds, a un control DataGrid denominado dg:
Visual Basic .NET dg.DataSource = ds
dg.DataMember = "Authors"
dg.DataBind()
C# dg.DataSource = ds;
dg.DataMember = "Authors";
dg.DataBind();
Acceso a datos con Microsoft ADO.NET 27
C# dg.DataSource = ds.Tables["Authors"];
dg.DataBind();
Si deseamos mostrar una vista distinta de los datos del control DataGrid,
deberemos crear un nuevo objeto DataView desde el objeto DataSet y vincular
ese objeto al control.
Ejemplo de uso de una El siguiente código de ejemplo muestra cómo vincular un objeto DataView dv,
vista personalizada filtrado para el estado de California, a un control DataGrid dg:
Visual Basic .NET Dim dv As New DataView(ds.Tables("Authors"))
dv.RowFilter = "state = 'CA'"
dg.DataSource = dv
dg.DataBind()
*****************************
Introducción En esta práctica dirigida por el instructor, examinaremos código que crea y
rellena un objeto DataSet, crea un objeto DataView utilizando datos
clasificados y filtrados del objeto DataSet, y vincula los controles DataGrid a
los objetos DataSet y DataView.
Gestión de errores
La conexión no se abre
z La cadena de conexión no es válida
z El servidor o la base de datos no se encuentran
z Fallo de inicio de sesión
El DataAdapter no puede crear un DataSet
z Sintaxis SQL no válida
z Nombre de tabla o campo no válido
Código de ejemplo
*****************************
Introducción Existen dos fuentes principales de error cuando intentamos acceder a datos
desde un formulario Web Form utilizando ADO.NET: problemas de conexión y
una falta de alineación con la base de datos.
La conexión no se abre Cuando se invoca el método Open, puede producirse más de un error. Ante la
posibilidad de que ocurra más de un error, debemos ser capaces de gestionar
múltiples errores utilizando las instrucciones Try…Catch…Finally. Si se
produce una o más excepciones SqlException, podemos recorrer todos los
objetos de excepciones SQL devueltos a nuestra aplicación Web.
El siguiente código muestra cómo utilizar una instrucción Try...Catch para
capturar múltiples tipos de excepciones. En este ejemplo, el código captura el
tipo de excepción InvalidOperationException, junto con otras excepciones,
utilizando un procesador de excepciones genérico:
30 Acceso a datos con Microsoft ADO.NET
C# try
{
SqlConnection conn = new SqlConnection("...");
SqlDataAdapter da = new SqlDataAdapter("...",conn);
DataSet ds = new DataSet();
da.Fill(ds);
}
catch (System.Data.SqlClient.SqlException ex1)
{
switch(ex1.Number)
{
case 17:
lblErrors.Text = lblErrors.Text +
("invalid Server name");
break;
case 156:
case 170: //bad SQL syntax
lblErrors.Text = lblErrors.Text +
("incorrect syntax");
break;
case 207: //bad field name in select
lblErrors.Text = lblErrors.Text +
("invalid column name");
break;
case 208: //bad table name in select
lblErrors.Text = lblErrors.Text +
("invalid object name");
break;
case 18452:
lblErrors.Text = lblErrors.Text +
("invalid user name");
break;
case 18456:
lblErrors.Text = lblErrors.Text +
("invalid password");
break;
case 4060:
lblErrors.Text = lblErrors.Text +
("invalid database");
break;
}
}
catch (System.Exception ex2)
{
lblErrors.Text = lblErrors.Text +
("Unexpected exception: " + ex2.Message + ". ");
}
32 Acceso a datos con Microsoft ADO.NET
El DataAdapter no La clase SqlException contiene la excepción que se lanza cuando SQL Server
puede crear un DataSet devuelve un aviso o error. Esta clase se crea siempre que el Proveedor de Datos
.NET de SQL Server encuentra una situación que no puede gestionar. La clase
SqlException siempre contiene al menos la instancia de un objeto SqlError.
Podemos utilizar el nivel de severidad de la clase para que nos ayude a
determinar el contenido de un mensaje mostrado por una excepción.
Para capturar objetos SqlException, debemos buscar errores de tipo
System.Data.SqlClient.SqlException. Cuando se produce un objeto
SqlException, el objeto de excepción contiene una colección Errors.
El siguiente ejemplo muestra cómo podemos recorrer la colección Errors para
encontrar información sobre los errores que se han producido:
Visual Basic .NET Dim erData As SqlClient.SqlErrorCollection = ex1.Errors
Dim i As Integer
For i = 0 To erData.Count - 1
lblErrors.Text &= ("Error " & i & ": " & _
erData(i).Number & ", " & _
erData(i).Class & ", " & _
erData(i).Message & "<br>")
Next i
Errores de SQL Server Los errores de SQL Server comparten propiedades comunes y están
identificados por un número y un nivel de gravedad:
La clase SqlError y propiedades comunes
Cada objeto SqlError tiene las propiedades comunes que se muestran en la
siguiente tabla.
Propiedad Descripción
Class Obtiene el nivel de gravedad del error devuelto por SQL Server.
LineNumber Obtiene el número de línea del archivo de proceso por lotes con
comandos Transact-SQL o el procedimiento almacenado que
contiene el error.
Message Obtiene el texto que describe el error.
Number Obtiene un número que identifica el tipo de error.
*****************************
Introducción Uno de los puntos fuertes de los objetos DataSet es que pueden contener
múltiples objetos DataTable, y cada objeto DataTable puede provenir de una
fuente distinta.
En esta lección, estudiaremos cómo almacenar múltiples tablas de datos en un
objeto DataSet y cómo mostrar esos datos en controles DataGrid.
Objetivos de la lección En esta lección, aprenderemos a:
Almacenar datos en múltiples tablas de múltiples fuentes.
Crear relaciones entre datos de múltiples fuentes de datos.
Utilizar relaciones para navegar entre tablas de datos de múltiples fuentes.
Acceso a datos con Microsoft ADO.NET 35
conn1 conn2
DataSet Orders
*****************************
Introducción Para rellenar un objeto DataSet con múltiples objetos DataTable que
provienen de una o más fuentes de datos, debemos utilizar múltiples objetos
DataAdapter. Cada objeto DataAdapter rellena una tabla distinta del objeto
DataSet. Como el orden de los objetos DataAdapter controla el orden de
implementación, podemos controlar el orden en que se escriben las
actualizaciones a y desde la base de datos. Este control sobre el orden de
implementación nos ayuda a conservar la integridad referencial entre las tablas
relacionadas de la base de datos.
Agregar la primera tabla Un ejemplo de control del orden en que se crean los objetos DataTable podría
ser un responsable de ventas que necesita recuperar información de clientes, e
información sobre órdenes de compra realizadas por cada cliente, desde una
base de datos central. Para satisfacer este requerimiento, podemos crear una
aplicación Web que contenga dos objetos DataAdapter, el primero para
recuperar registros de clientes y el segundo para recuperar registros de órdenes
de compra. Cargando primero los datos de los clientes, podemos conservar la
integridad referencial entre los clientes y sus órdenes de compra.
36 Acceso a datos con Microsoft ADO.NET
C# SqlConnection conn;
SqlDataAdapter daCustomers;
SqlDataAdapter daOrders;
DataSet ds = new DataSet();
Agregar tablas Después de cargar el primer objeto DataTable, podemos rellenar objetos
subsiguientes DataTable adicionales y definir las relaciones entre los objetos basadas en el
objeto DataTable inicial. Siguiendo con el ejemplo anterior, rellenaríamos el
objeto Orders DataTable.
El siguiente código puebla el objeto Orders DataTable utilizando un objeto
DataAdapter denominado daOrders:
Visual Basic .NET 'Create the second DataTable
daOrders = New SqlDataAdapter _
("select CustomerID, OrderID, OrderDate, ShippedDate " & _
"from Orders", conn)
daOrders.Fill(ds, "Orders")
Crear relaciones
Dim
Dim dr
dr As
As New
New DataRelation
DataRelation __
("name",
("name", parentCol,
parentCol, __
childCol)
childCol)
ds.DataRelations.Add(dr) childCol
ds.DataRelations.Add(dr) DataSet Tabla Orders
Código de ejemplo C#
*****************************
Introducción Se utiliza un objeto DataRelation para referenciar dos objetos DataTable entre
sí a través de objetos DataColumn. Por ejemplo, en una relación
Customer/Orders, Customers es la tabla primaria de la relación y Orders es la
secundaria. Esta relación es similar a una relación clave principal/clave foránea.
Las relaciones se crean entre columnas coincidentes de las tablas primaria y
secundaria. El valor de DataType para ambas columnas debe ser idéntico.
Los objetos DataRelation están contenidos en un objeto
DataRelationCollection, al que podemos acceder no sólo a través de la
propiedad Relations del objeto DataSet, sino también a través de las
propiedades ChildRelations y ParentRelations del objeto DataTable.
Para crear un objeto DataRelation, utilizamos el constructor DataRelation y el
método Add de la colección Relations de un objeto DataSet.
38 Acceso a datos con Microsoft ADO.NET
parentCol = ds.Tables("Customers").Columns("CustomerID")
childCol = ds.Tables("Orders").Columns("CustomerID")
dr = New DataRelation("CustOrders", parentCol, childCol)
ds.Relations.Add(dr)
parentCol = ds.Tables["Customers"].Columns["CustomerID"];
childCol = ds.Tables["Orders"].Columns["CustomerID"];
dr = new DataRelation("CustOrders", parentCol, childCol);
ds.Relations.Add(dr);
Nota Para más información sobre relaciones de datos, ver “Explorar una
relación entre tablas,” en la documentación de Visual Studio .NET.
Acceso a datos con Microsoft ADO.NET 39
ds.Tables(index).Rows(index).GetChildRows("relation")
ds.Tables(index).Rows(index).GetChildRows("relation")
ds.Tables(index).Rows(index).GetParentRow("relation")
ds.Tables(index).Rows(index).GetParentRow("relation")
ds.Tables[index].Rows[index].GetChildRows("relation");
ds.Tables[index].Rows[index].GetChildRows("relation");
ds.Tables[index].Rows[index].GetParentRow("relation");
ds.Tables[index].Rows[index].GetParentRow("relation");
Customers Orders
GetChildRows
GetParentRow
DataSet
*****************************
C# currentParentRow = ds.Tables["Customers"].
Rows[dgCustomers.SelectedIndex];
foreach(DataRow r
in currentParentRow.GetChildRows("CustOrders"))
{
Label1.Text += r["OrderID"] + ",";
}
Acceso a datos con Microsoft ADO.NET 41
DataView
DataView tableView;
tableView;
DataRowView
DataRowView currentRowView;
currentRowView;
tableView
tableView == new
new DataView(ds.Tables["Customers"]);
DataView(ds.Tables["Customers"]);
currentRowView
currentRowView == tableView[dgCustomers.SelectedIndex];
tableView[dgCustomers.SelectedIndex];
dgChild.DataSource
dgChild.DataSource == currentRowView.CreateChildView("CustOrders");
currentRowView.CreateChildView("CustOrders");
Customers Orders
DataRowView
DataView CreateChildView
DataSet
*****************************
Navegar visualmente Con Visual Studio .NET también podemos mostrar relaciones arrastrando
controles desde el cuadro de herramientas. Si deseamos mostrar las filas
secundarias de una relación en otro control enlazado a lista, podemos utilizar el
método CreateChildView y vincular el control enlazado a lista al objeto
DataView resultante.
Para conectar dos controles enlazados a lista a través de un objeto
DataRelation, necesitamos obtener el objeto DataRowView de la fila
seleccionada del control enlazado a lista primario, e invocar el método
CreateChildView del objeto DataRowView.
El siguiente código crea un objeto DataView desde un objeto DataRelation
para mostrar registros secundarios en un control DataGrid:
Visual Basic .NET Dim parentTableView As New _
DataView(ds.Tables("Customers"))
Dim currentRowView As DataRowView = _
parentTableView(dgCustomers.SelectedIndex)
dgChild.DataSource = _
currentRowView.CreateChildView("CustOrders")
dgChild.DataBind()
dgChild.DataSource =
currentRowView.CreateChildView("CustOrders");
dgChild.DataBind();
42 Acceso a datos con Microsoft ADO.NET
Programáticamente:
z Crear un DataSet
z Crear un DataRelation
z Mostrar registros secundarios utilizando
DataRelation
Visualmente:
z Invocar CreateChildView
*****************************
¿Qué es un DataReader?
Crear un DataReader
Leer datos de un DataReader
Vincular un DataReader a un control enlazado a lista
Práctica: organizar código para crear un DataReader
Demostración: mostrar datos utilizando DataReaders
*****************************
¿Qué es un DataReader?
*****************************
Introducción Cuando se recupera una gran cantidad de datos de una fuente de datos,
mantener la memoria abierta puede ser un problema. Por ejemplo, leer 10.000
filas de una base de datos hace que un objeto DataTable asigne y mantenga
memoria para esas 10.000 filas durante la vida de la tabla. Si 1.000 usuarios
hacen esto contra el mismo equipo a la vez, el uso de la memoria será un factor
crítico. Para abordar estas situaciones del uso de memoria, la clase DataReader
está diseñada para producir un flujo de datos de sólo lectura y sólo hacia delante
que la base de datos devuelve. Por tanto, sólo hay un registro en memoria cada
vez en el servidor.
Sólo hacia delante, sólo La clase DataReader proporciona una transferencia de datos de sólo lectura y
lectura sólo hacia delante que puede vincularse a un control enlazado a lista. Por
ejemplo, si sólo deseamos mostrar los resultados de una consulta a una base de
datos en un único control enlazado a lista, y si no vamos a manipular esos
datos, una clase DataReader es una forma ideal de conseguirlo.
Acceso rápido a datos Los objetos DataReader son más rápidos que los objetos DataSet por la
naturaleza ligera de la clase DataReader. En la creación del objeto DataSet, la
sobrecarga es mayor debido a que los objetos DataSet tienen la capacidad de
leer y escribir datos y examinar hacia delante y hacia atrás. Hay muy poca
sobrecarga en un objeto DataReader ya que es sólo hacia delante y sólo de
lectura. Esta relativa falta de sobrecarga supone un acceso a datos más rápido
con un objeto DataReader que con un objeto DataSet.
Conexión a la fuente de ADO.NET incluye dos tipos de objetos DataReader: el objeto SqlDataReader
datos para datos SQL Server versión 7.0 o posterior, y el objeto OleDbDataReader
para datos OLE DB Data Provider. Utilizamos los objetos OleDbCommand y
SqlCommand, y el método ExecuteReader, para transferir datos a un objeto
DataReader.
46 Acceso a datos con Microsoft ADO.NET
Crear un DataReader
2.
22 Crear un objeto Command
3.
33 Crear un DataReader desde el objeto Command
4.
44 Invocar el método ExecuteReader
5.
55 Utilizar el objeto DataReader
6.
66 Cerrar el objeto DataReader
7.
77 Cerrar el objeto Connection
Código de ejemplo
*****************************
El siguiente código de ejemplo abre una conexión a una base de datos, crea un
objeto DataReader desde un objeto Command, y recorre el objeto
DataReader y agrega campos de los registros a un control ListBox:
Visual Basic .NET 'Create connection and command objects
Dim conn As New SqlConnection _
("data source=localhost;integrated security=true;" & _
"initial catalog=pubs")
Dim cmdAuthors As New SqlCommand _
("select * from Authors", conn)
conn.Open()
Utilizar el controlador de Cuando se utilizan conexiones con el objeto DataReader, debemos utilizar
eventos siempre una instrucción Try…Catch…Finally para garantizar que si algo falla,
Try…Catch…Finally la conexión se cerrará. De lo contrario, la conexión puede permanecer abierta
de forma indefinida.
El siguiente código de un objeto DataReader captura errores y cierra la
conexión:
Visual Basic .NET Try
conn.Open()
dr = cmdAuthors.ExecuteReader()
'use the returned data in the DataReaders
Catch e As Exception
'handle the error
Finally
dr.Close()
conn.Close()
End Try
C# try
{
conn.Open();
dr = cmdAuthors.ExecuteReader();
// use the returned data in the DataReaders
}
catch(Exception e)
{
// Handle error
}
finally
{
dr.Close();
conn.Close();
}
50 Acceso a datos con Microsoft ADO.NET
Do
Do While
While myReader.Read() while
myReader.Read() while (myReader.Read())
(myReader.Read())
str
str &=
&= myReader(1)
myReader(1) {{
str
str &=
&= myReader("field") str
myReader("field") str +=
+= myReader[1];
myReader[1];
str
str &=
&= myReader.GetDateTime(2) str
myReader.GetDateTime(2) str +=
+= myReader["field"];
myReader["field"];
Loop
Loop str += myReader.GetDateTime(2);
str += myReader.GetDateTime(2);
}}
Cerrar el DataReader
Cerrar la conexión
*****************************
Invocar Read para cada Tras invocar el método ExecuteReader del objeto Command, podemos
registro acceder a un registro del objeto DataReader invocando el método Read. El
objeto DataReader se posiciona de modo predeterminado antes del primer
registro; por tanto, debemos invocar el método Read antes de acceder a algún
dato. Cuando ya no hay más registros disponibles, el método Read devuelve un
valor nulo.
El siguiente código recorre todos los registros de un objeto DataReader dr, y
muestra el campo au_fname en el control Label lblName:
Visual Basic .NET Do While dr.Read()
lblName.Text &= dr("au_fname")
Loop
C# while (dr.Read())
{
lblName.Text += dr["au_name"];
}
Acceso a datos con Microsoft ADO.NET 51
Acceso a campos Para obtener los datos de los campos del registro actual, podemos acceder a un
campo por su posición ordinal, por su nombre o invocando un método Get
adecuado, como GetDateTime, GetDouble, GetInt32 o GetString.
Sugerencia Utilizar un método Get específico es más rápido que acceder por
la posición ordinal o por el nombre, porque el DataReader no necesita
comprobar el formato de los datos.
Por ejemplo, el siguiente código de ejemplo lee los campos del primer y último
nombre, ambos valores de cadena, desde el primer registro del objeto
DataReader dr, utilizando el método GetString():
Visual Basic .NET dr.Read()
lblName.Text = dr.GetString(1) + ", " + _
dr.GetString(2)
C# dr.Read();
lblName.Text = dr.GetString(1) + ", " +
dr.GetString(2);
También podemos referenciar, por nombre, los campos de datos del registro
actual del objeto DataReader. Seguidamente, podemos invocar una función de
conversión apropiada, como muestra el siguiente código de ejemplo:
Visual Basic .NET myReader("au_fname")
C# myReader["au_fname"];
Cerrar el DataReader Mientras el objeto DataReader está en uso, la conexión asociada está ocupada
dando servicio al objeto DataReader. Por tanto, debemos invocar el método
Close para cerrar el objeto DataReader cuando finalicemos su uso, como
muestra el siguiente código de ejemplo:
Visual Basic .NET myReader.Close()
C# myReader.Close();
C# conn.Close();
52 Acceso a datos con Microsoft ADO.NET
Crear el control
<asp:DataGrid
<asp:DataGrid id="dgAuthors"
id="dgAuthors" runat="server"
runat="server" />
/>
Vincular a un DataReader
dgAuthors.DataSource
dgAuthors.DataSource == dr
dr dgAuthors.DataSource
dgAuthors.DataSource == dr;
dr;
dgAuthors.DataBind()
dgAuthors.DataBind() dgAuthors.DataBind();
dgAuthors.DataBind();
*****************************
Los estudiantes:
z Reordenarán líneas de código para crear
un DataReader
Tiempo: 5 minutos
*****************************
Ë Ejecutar la práctica
• Visualizar la página http://localhost/Mod10VB/DataReaderCode.aspx o
http://localhost/Mod10CS/DataReaderCode.aspx y colocar las líneas de
código ADO.NET en el orden correcto para crear un objeto DataReader.
*****************************
Ë Ejecutar la demostración
1. Abrir la página DataReader.aspx del proyecto Demo08VB o Demo08CS
que se pueden encontrar dentro del fichero demos08.zip.
2. Generar y examinar la página DataReader.aspx.
Hay dos cuadros de lista que muestran los mismos datos. El primer cuadro
de lista está vinculado a un objeto DataReader, mientras que el segundo
cuadro de lista se genera recorriendo los registros del objeto DataReader y
generando programáticamente cada entrada del control ListBox.
3. En Visual Studio .NET, visualizar el código subyacente de la página
DataReader.aspx.
4. En el procedimiento de evento Page_Load, mostrar el código que hace lo
siguiente:
• Crea un objeto SqlConnection.
• Crea un objeto SqlCommand.
• Crea un objeto DataReader.
• Vincula el objeto DataReader al primer control ListBox.
• Cerrar el objeto DataReader y crearlo de nuevo.
Este paso es necesario debido a que un objeto DataReader es una vista
de los datos sólo hacia delante y ya habíamos llegado al final de los
datos cuando el objeto DataReader se vinculó al control ListBox.
• Recorre el objeto DataReader y agrega dos campos por cada elemento
del segundo control ListBox.