8.-_Acceso_a_datos_c..

Anuncio
Acceso a datos con Microsoft
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
Lección: introducción al uso de ADO.NET
„
Multimedia: modelo de objetos ADO.NET
„
Utilizar DataSets frente a DataReaders
„
Práctica: cuándo utilizar DataSets o DataReaders
*****************************
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
Uso de DataSets frente a DataReaders
DataSet
DataReader
Acceso lectura/escritura a
datos
Sólo lectura
Incluye múltiples tablas de
distintas bases de datos
Basado en una instrucción SQL
de una base de datos
Desconectado
Conectado
Vinculado a múltiples controles
Vinculado a un único control
Búsqueda de datos hacia
delante y hacia atrás
Sólo hacia delante
Acceso más lento
Acceso más rápido
Soportado por las herramientas
de Visual Studio .NET
Codificación manual
*****************************
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
DataReaders
La elección entre utilizar objetos DataSet u objetos DataReader debería
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
Si nuestra intención es enlazar los datos a más de un control, debemos
utilizar un objeto DataSet. Los objetos DataReader sólo pueden vincularse
a un único control.
„
Modo conexión
Si nuestra intención es trabajar en un modo desconectado, debemos utilizar
un objeto DataSet. Los objetos DataReader deben ejecutarse en modo
conectado.
„
Búsqueda (scanning) de datos
Si nuestra intención es buscar los datos hacia atrás y hacia delante, debemos
utilizar un objeto DataSet. Los objetos DataReader buscan hacia adelante a
medida que los datos fluyen desde la base de datos.
„
Velocidad de acceso
Si necesitamos acceso de alta velocidad a nuestra fuente de datos,
utilizaremos un objeto DataReader. Los objetos DataSet son más lentos
que los objetos DataReader en el acceso a una base de datos, debido a que
los objetos DataSet almacenan los datos en un objeto del servidor Web.
También la sobrecarga es mayor en la creación del objeto DataSet debido a
la capacidad de leer y escribir datos y búsqueda hacia delante y hacia atrás.
Los objetos DataReader son más rápidos debido a la naturaleza del objeto
más ligera. Hay muy poca sobrecarga para el objeto DataReader, ya que
éste trabaja sólo hacia delante y sólo de lectura.
„
Soporte de herramientas
Si nuestra intención es utilizar Microsoft Visual Studio® .NET para crear la
conexión a datos, utilizaremos objeto DataSet. Con los objetos DataSet,
podemos elegir entre escribir nuestro propio código o utilizar el código
máquina de Visual Studio .NET. Con los objetos DataReader, debemos
escribir todo el código de soporte.
Acceso a datos con Microsoft ADO.NET
5
Práctica: cuándo utilizar DataSets o DataReaders
„
Los estudiantes:
z
„
Seleccionarán la mejor opción de acceso
a datos para determinados escenarios
Tiempo: 5 minutos
*****************************
Ë Leer los siguientes escenarios, y decidir si es mejor utilizar un objeto
DataSet o un objeto DataReader
Deseamos obtener información de dos tablas que se encuentran en dos bases
de datos distintas, y mostrar las tablas al usuario.
____________________________________________________________
____________________________________________________________
Deseamos obtener información de una tabla en una base de datos, permitir
al usuario modificar los datos y almacenar esos cambios en la base de datos.
____________________________________________________________
____________________________________________________________
Deseamos obtener información de dos tablas de la misma base de datos y
mostrar esa información al usuario.
____________________________________________________________
____________________________________________________________
Deseamos obtener información de una tabla de una base de datos y dejar al
usuario visualizar los datos en múltiples configuraciones distintas.
____________________________________________________________
____________________________________________________________
6
Acceso a datos con Microsoft ADO.NET
Lección: conexión a una base de datos
„
Seguridad SQL Server
„
Crear la conexión
„
Demostración: establecer la seguridad SQL Server
*****************************
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
Seguridad SQL Server
Servidor
ServidorWeb
Web
Configuración
ConfiguraciónASP.NET
ASP.NET
predeterminada
predeterminada
Aquí está el
nombre de usuario
y la contraseña
Autenticación
Autenticación
modo
modomixto
mixto
Enviar el nombre de
usuario y contraseña
en texto claro.
Servidor
ServidorSQL
SQL
Cada
Cadacuenta
cuentade
deusuario
usuariose
se
agrega
agregaaa grupo
grupologin
loginde
deSQL
SQLServer
Server
o…
o…
Cliente
Cliente
Autenticación
Autenticación
sólo
sóloWindows
Windows
Servidor
ServidorWeb
Web
Autenticación
AutenticaciónWindows
Windows
No enviar el nombre de
usuario y contraseña.
Enviar sólo que el
usuario ha sido
autenticado.
Servidor
ServidorSQL
SQL
Sólo
Sólolalacuenta
cuentaASPNET
ASPNET
tiene
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
mixto
La autenticación en modo mixto utiliza la configuración predeterminada de
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
Aviso Utilizar la autenticación en modo mixto para acceder a SQL Server
desde una aplicación Web es un riesgo de seguridad y no está recomendado. La
autenticación en modo mixto se describe aquí como una técnica que puede
utilizarse durante el desarrollo de la aplicación Web.
Autenticación sólo
Windows
La autenticación en modo sólo Windows es el método más utilizado para
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
Configurar el SQL
Server para ejecutar
autenticación
en modo mixto o sólo
Windows
9
Cuando utilizamos la autenticación en modo sólo Windows, podemos mantener
a SQL Server en el modo de autenticación predeterminado de sólo Windows. Si
utilizamos la autenticación en modo mixto, necesitamos modificar el modo de
autenticación de SQL Server.
Ë 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 As
As 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);
„
Establecer los parámetros de la cadena de conexión
z
Timeout de conexión
z
Contraseña
z
Fuente de datos
z
Persistir información seguridad
z
Catálogo inicial
z
Proveedor
z
Seguridad integrada
z
ID de usuario
*****************************
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
conexión
Creamos un objeto SqlConnection pasando una cadena de conexión que
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
Parámetros de la cadena
de conexión
11
La siguiente tabla describe algunos de los parámetros más habituales de un
objeto de conexión:
Parámetro
Descripción
Connection Timeout
El intervalo de tiempo de espera en segundos en una conexión
al servidor antes de finalizar el intento y generar una
excepción. 15 segundos es el tiempo predeterminado.
Data Source
El nombre del servidor SQL Server utilizado cuando se abre
una conexión, o el nombre del archivo que se utiliza cuando en
la conexión a una base de datos Microsoft Access.
Initial Catalog
El nombre de la base de datos.
Integrated Security
El parámetro que determina si la conexión es o no segura. Los
valores posibles son True, False y SSPI. SSPI es el
equivalente a True.
Password
La contraseña de inicio de sesión en la base de datos SQL
Server.
Persist Security Info
Cuando está establecido a False no se devuelve información
sensible a la seguridad (como la contraseña) como parte de la
conexión, si la conexión está abierta o ha estado en un estado
abierto. Establecer esta propiedad a True puede constituir un
riesgo de seguridad. La configuración predeterminada es False.
Provider
La propiedad que se utiliza para establecer o devolver el
nombre del proveedor de la conexión; este parámetro se utiliza
únicamente para objetos OleDbConnection.
User ID
El nombre de cuenta de inicio de sesión de SQL Server.
12
Acceso a datos con Microsoft ADO.NET
Demostración: establecer la seguridad de SQL Server
„ Abrir SQL Server Enterprise Manager
„ Establecer el modo
de autenticación
„ Probar con seguridad
integrada
„ Probar con seguridad
en modo mixto
*****************************
Introducción
En esta demostración, veremos cómo establecer y probar una conexión de
seguridad integrada entre una aplicación Web y un SQL Server.
Ë Ejecutar esta demostración
Abrir SQL Server
Enterprise Manager
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 expandir la carpeta Servidores Microsoft SQL Server.
3. Hacer clic con el botón derecho en el servidor SQL Server (local) y clic en
Propiedades.
Establecer el modo de
autenticación
4. En el cuadro de diálogo Propiedades de SQL Server, en la ficha
Seguridad, hacer clic en el botón de opción Sólo Windows de la sección
Autenticación y hacer clic en Aceptar.
5. Abrir el formulario Web Form SQLSecurityModes.aspx del proyecto
Demo08VB o Demo08CS ue se pueden encontrar dentro del fichero
demos08.zip
6. Generar y examinar la página SQLSecurityModes.aspx.
Prueba con seguridad
integrada
7. Hacer clic en Utilizar seguridad integrada, y clic en Get Data.
Los datos se recuperan de la base de datos y se muestran en el control
DataGrid.
8. Hacer clic en Utilizar seguridad estándar, y clic en Get Data.
Obtenemos un error porque el usuario no existe en el SQL Server.
9. Crear un nuevo usuario para SQL Server:
a. En la consola Gestión de equipos, expandir la carpeta SQL Server
(local) y expandir la carpeta Seguridad.
b. Hacer clic con el botón derecho en Logins y hacer clic en Nuevo Login.
Acceso a datos con Microsoft ADO.NET
13
c. En el cuadro de diálogo Propiedades de login de SQL Server, escribir
CohoUser en el campo Nombre, hacer clic en Autenticación SQL
Server en la sección Autenticación, escribir 1Coho en el campo
Contraseña, y hacer clic en Aceptar.
d. Teclear 1Coho en el cuadro de diálogo Confirmar contraseña, y hacer
clic en Aceptar.
Prueba con seguridad
en modo mixto
10. Cambiar el modo de autenticación de SQL Server a modo mixto.
a. En la consola Gestión de equipos, hacer clic con el botón derecho en
SQL Server (local) y clic en Propiedades.
b. 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 de
la sección Autenticación, y hacer clic en Aceptar.
c. A la pregunta de si es necesario reiniciar el servicio SQL Server, hacer
clic en Sí.
11. Visualizar la página SQLSecurityModes.aspx en el navegador de nuevo y
probar ambos métodos para acceder a SQL Server. Ahora, funcionarán los
dos métodos.
14
Acceso a datos con Microsoft ADO.NET
Lección: acceso a datos con DataSets
„
Crear un DataAdapter
„
Crear un DataSet
„
Demostración: utilizar programáticamente un DataSet
„
Utilizar un DataView
„
Práctica: organizar código para crear un DataSet
„
Vincular un DataSet a un control enlazado a lista
„
Práctica dirigida por el instructor: visualizar un
DataSet
„
Gestión de errores
*****************************
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
„
Almacenar la consulta en un DataAdapter
Dim
Dim da
da As
As New
New SqlDataAdapter
SqlDataAdapter __
("select
("select ** from
from Authors",
Authors", conn)
conn)
SqlDataAdapter
SqlDataAdapter da
da == new
new SqlDataAdapter
SqlDataAdapter
("select
("select ** from
from Authors",conn);
Authors",conn);
„
El constructor DataAdapter establece la propiedad
SelectCommand
da.SelectCommand.CommandText
da.SelectCommand.CommandText
da.SelectCommand.Connection
da.SelectCommand.Connection
da.SelectCommand.CommandText;
da.SelectCommand.CommandText;
da.SelectCommand.Connection;
da.SelectCommand.Connection;
„
Establecer las propiedades InsertCommand,
UpdateCommand y DeleteCommand si fuera necesario
*****************************
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
DataAdapter
Cuando utilizamos objetos DataAdapter para intercambiar datos entre un
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
SelectCommand
La propiedad SelectCommand recupera filas de la fuente de
datos.
InsertCommand
La propiedad InsertCommand escribe filas insertadas del
DataSet a la fuente de datos.
UpdateCommand
La propiedad UpdateCommand escribe filas modificadas del
DataSet a la fuente de datos.
DeleteCommand
La propiedad DeleteCommand elimina filas en la fuente de
datos.
Ejemplo de
SqlDataAdapter
El siguiente código de ejemplo muestra cómo crear un objeto SqlDataAdapter
denominado da que contiene una sentencia de consulta:
Visual Basic .NET
'Create a connection
Dim conn As New SqlConnection _
("data source=localhost;initial catalog=pubs;" & _
"integrated security=true;persist security info=True;")
'Create the DataAdapter
Dim da As New SqlDataAdapter _
("select * from Authors", conn)
C#
//Create a connection
SqlConnection conn = new SqlConnection
("data source=localhost; initial catalog=pubs; " +
"integrated security=true; persist security info=True;");
//Create the DataAdapter
SqlDataAdapter da = new SqlDataAdapter
("select * from Authors", conn);
Acceso a datos con Microsoft ADO.NET
17
Crear un DataSet
„
Crear y poblar un DataSet con DataTables
z
El método Fill ejecuta el SelectCommand
DataSet
DataSet ds
ds == new
new DataSet();
DataSet();
da.Fill(ds,
da.Fill(ds, "Authors");
"Authors");
„
Dim
Dim ds
ds As
As New
New DataSet()
DataSet()
da.Fill(ds,
da.Fill(ds, "Authors")
"Authors")
Acceder a DataTable
ds.Tables["Authors"].Rows.Count;
ds.Tables["Authors"].Rows.Count;
string
string str="";
str="";
foreach(DataRow
foreach(DataRow rr in
in
ds.Tables["Authors"].Rows)
ds.Tables["Authors"].Rows)
{{
str
str +=
+= r[2];
r[2];
str
str +=
+= r["au_lname"];
r["au_lname"];
}}
ds.Tables("Authors").Rows.Count
ds.Tables("Authors").Rows.Count
Dim
Dim rr As
As DataRow
DataRow
Dim
Dim str
str As
As String
String
For
For Each
Each rr in
in __
ds.Tables("Authors").Rows
ds.Tables("Authors").Rows
str
str &=
&= r(2)
r(2)
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()
C#
DataSet ds = 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");
El método Fill ejecuta implícitamente una consulta SQL en la propiedad
SelectCommand del objeto DataAdapter. Los resultados de la consulta SQL
se utilizan para definir la estructura del objeto DataTable, y para poblar la tabla
con datos.
18
Acceso a datos con Microsoft ADO.NET
El siguiente código de ejemplo muestra cómo crear un objeto SqlDataAdapter
da, e invocar a continuación el método Fill para almacenar los datos en el
objeto DataSet ds.
Visual Basic .NET
'Create a connection
Dim conn As New SqlConnection _
("data source=localhost;initial catalog=pubs;" & _
"integrated security=SSPI;persist security info=True;")
'Create the DataSet
Dim ds As New DataSet()
'Create the DataAdapter
Dim da As New SqlDataAdapter _
("select * from Authors", conn)
'Fill the DataSet ds
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;");
//Create the DataSet
DataSet ds = new DataSet();
//Create the DataAdapter
SqlDataAdapter da = new SqlDataAdapter
("select * from Authors", conn);
//Fill the DataSet ds
da.Fill(ds, "Authors");
El segundo argumento del método Fill es un nombre para el objeto DataTable
que está creado. Utilizamos este nombre para acceder a los datos devueltos.
Acceder a DataTable
Una vez insertados los datos en un objeto DataSet, podemos acceder
programáticamente a los datos. Como muestra el siguiente código, cada objeto
DataSet está formado por uno o más objetos DataTable a los que podemos
hacer referencia por su nombre o posición ordinal:
Visual Basic .NET
ds.Tables("Authors")
-ods.Tables(0)
C#
ds.Tables["Authors"];
-ods.Tables[0];
Acceso a datos con Microsoft ADO.NET
19
Las clases DataRow y DataColumn son los componentes principales de una
clase DataTable. Utilizaríamos un objeto DataRow con sus propiedades y
métodos para recuperar y evaluar los valores de un objeto DataTable.
DataRowCollection representa los objetos DataRow reales que se encuentran
en el objeto DataTable, y DataColumnCollection contiene los objetos
DataColumn que describen el esquema del objeto DataTable. La propiedad
Rows del objeto DataTable proporciona acceso programático a
DataRowCollection. La propiedad Columns del objeto DataTable
proporciona acceso programático a DataColumnCollection.
El siguiente código de ejemplo agrega los nombres de columnas de un objeto
DataSet al control ListBox denominado lstItems:
Visual Basic .NET
Dim col As DataColumn
For Each col In ds.Tables(0).Columns
lstItems.Items.Add(col.ColumnName)
Next
C#
foreach(DataColumn col in ds.Tables[0].Columns)
{
lstItems.Items.Add(col.ColumnName);
}
Tanto el objeto DataRowCollection como el objeto DataColumnCollection
tienen una propiedad Count que nos permite determinar el número de filas o
columnas de un objeto DataTable, como muestra el siguiente código de
ejemplo:
Visual Basic .NET
ds.Tables("Authors").Rows.Count
ds.Tables("Authors").Columns.Count
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
El siguiente código recorre en bucle cada fila del objeto DataTable
denominado Authors y crea una cadena utilizando los campos segundo y
au_lname de Authors:
Visual Basic .NET
Dim r As DataRow
Dim str As String
For Each r in ds.Tables("Authors").Rows
str &= r(1)
str &= r("au_lname")
Next
C#
string str = "";
foreach(DataRow r in ds.Tables["Authors"].Rows)
{
str += r[1];
str += r["au_lname"];
}
Acceso a datos con Microsoft ADO.NET
21
Demostración: utilizar programáticamente un DataSet
„
Crear una conexión
„
Crear DataAdapter
„
Crear DataSet
„
Leer los datos del DataSet
programáticamente
*****************************
Introducción
En esta demostración, examinaremos código que crea y rellena un objeto
DataSet, y veremos cómo ese código rellena dinámicamente un control
ListBox desde el objeto DataSet.
Ë 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
6. En el procedimiento de evento Page_Load, mostrar el código que crea los
siguientes objetos:
• SqlConnection
• SqlDataAdapter
• DataSet
7. En el procedimiento de evento Page_Load, mostrar cómo la primera vez
que se muestra la página, el cuadro lista se rellena únicamente con los
nombres de columnas.
8. En el procedimiento de evento cmdRows_Click, mostrar cómo se recupera
el número de filas desde el DataSet.
9. En el procedimiento de evento cmdGetValues_Click, mostrar cómo se
recupera el campo seleccionado desde el DataSet.
Acceso a datos con Microsoft ADO.NET
23
Utilizar un DataView
„
Un DataView puede personalizarse para presentar un
subconjunto de datos de un DataTable
„
La propiedad DefaultView devuelve el DataView
predeterminado de la tabla
Dim
Dim dv
dv As
As DataView
DataView == ds.Tables("Authors").DefaultView
ds.Tables("Authors").DefaultView
DataView
DataView dv
dv == ds.Tables["Authors"].DefaultView;
ds.Tables["Authors"].DefaultView;
„
Establecer una vista distinta de un DataSet
Dim
Dim dv
dv As
As New
New DataView
DataView (ds.Tables("Authors"))
(ds.Tables("Authors"))
dv.RowFilter
dv.RowFilter == "state
"state == 'CA'"
'CA'"
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
subconjunto de un
DataTable
Los objetos DataView pueden personalizarse para presentar un subconjunto de
datos de un objeto DataTable. Esta personalización permite tener dos controles
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
DataView personalizado
También podemos crear un objeto DataView personalizado basado en un
subconjunto de datos que se encuentran en un objeto DataTable. Por ejemplo,
podemos establecer la propiedad DataView RowFilter utilizando una
expresión de filtro. La expresión de filtro puede tener el valor True o False.
También podemos establecer la propiedad Sort del objeto DataView utilizando
una expresión de clasificación. La expresión de clasificación puede incluir los
nombres de objetos DataColumn o un cálculo.
En el siguiente código, la propiedad RowFilter, de un objeto DataView dv,
está asignada para recuperar autores únicamente del estado de California y, a
continuación, ordenar los resultados por apellido:
Visual Basic .NET
Dim dv As New DataView(ds.Tables("Authors"))
dv.RowFilter = "state = 'CA'"
dv.Sort = "au_lname"
C#
DataView dv = new DataView(ds.Tables["Authors"]);
dv.RowFilter = "state = ‘CA’";
dv.Sort = "au_lname";
Acceso a datos con Microsoft ADO.NET
Práctica: organizar código para crear un DataSet
„
Los estudiantes:
z
„
Reordenarán líneas de código para crear
un DataSet
Tiempo: 5 minutos
*****************************
En esta práctica, reordenaremos líneas de código ADO.NET en el orden
correcto para crear un objeto DataSet.
Ë 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.
Nota Hay varias respuestas correctas para esta práctica.
25
26
Acceso a datos con Microsoft ADO.NET
Vincular un DataSet a un control enlazado a lista
„
Crear el control
<asp:DataGrid
<asp:DataGrid id="dg"
id="dg" runat="server"
runat="server" />
/>
„
Vincular a un DataSet o un DataView
dg.DataSource
dg.DataSource == ds
ds
dg.DataMember
dg.DataMember == "Authors"
"Authors"
dg.DataBind()
dg.DataBind()
dg.DataSource
dg.DataSource == ds;
ds;
dg.DataMember
dg.DataMember == "Authors";
"Authors";
dg.DataBind()
dg.DataBind();;
*****************************
Introducción
ASP.NET incluye un conjunto de controles enlazados a listas, como los
controles DataGrid, DataList y DataRepeater, que facilitan y flexibilizan la
visualización de datos desde una fuente de datos. Los desarrolladores
únicamente deben vincular estos controles a una fuente de datos para mostrar
los datos seleccionados.
Crear el control
El primer paso para vincular el objeto DataSet al control enlazado a lista es
crear el control. El siguiente código muestra cómo crear un control DataGrid
dg que produce la salida HTML parecida a una hoja de cálculo:
<asp:DataGrid id="dg" runat="server" />
Vincular a un Dataset o
DataView
Para vincular un objeto DataSet a un control DataGrid, en primer lugar
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
El siguiente código muestra cómo podemos utilizar también la colección
Tables del objeto DataSet ds para asignar el objeto DataTable Authors
directamente a la propiedad DataSource del control DataGrid denominado dg:
Visual Basic .NET
dg.DataSource = ds.Tables("Authors")
dg.DataBind()
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
vista personalizada
El siguiente código de ejemplo muestra cómo vincular un objeto DataView dv,
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()
C#
DataView dv = new DataView(ds.Tables["Authors"]);
dv.RowFilter = "state = 'CA'";
dg.DataSource = dv;
dg.Databind();
La siguiente ilustración muestra el formato predeterminado del control
DataGrid, mostrando datos de autores que viven en el estado de California.
28
Acceso a datos con Microsoft ADO.NET
Práctica dirigida por el instructor: mostrar un DataSet
„
Crear una conexión
„
Crear un DataAdapter
„
Crear un DataSet
„
Crear un DataView
„
Vincular DataSet y DataView a controles
DataGrid
*****************************
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.
Ë Ejecutar la práctica dirigida por el instructor
1. Abrir la página UseGrid.aspx del proyecto Mod10VB o Mod10CS de la
solución 2310Demos.
2. Generar y examinar la página UseGrid.aspx.
Hay dos controles DataGrid vinculados al mismo objeto DataSet. El
primer control DataGrid muestra todos los datos del objeto DataSet. El
segundo control DataGrid está vinculado a un objeto DataView, que filtra
y clasifica los datos. El segundo control DataGrid también implementa la
clasificación estableciendo la propiedad Sort del objeto DataView.
3. En Visual Studio .NET, visualizar el código subyacente de la página
UseGrid.aspx.
4. En el procedimiento de evento Page_Load, mostrar el código que hace lo
siguiente:
• Crea el objeto SqlConnection.
• Crea el objeto SqlDataAdapter.
• Crea un objeto DataSet.
• Vincula el primer control DataGrid con el objeto DataSet.
• Crea un objeto DataView y establece las propiedades RowFilter y Sort.
• Vincula el segundo control DataGrid con el objeto DataView.
Acceso a datos con Microsoft ADO.NET
29
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
Visual Basic .NET
Try
Dim conn As New SqlConnection(...)
Dim da As New SqlDataAdapter(..., conn)
Dim ds As New DataSet()
da.Fill(ds)
Catch ex1 As System.Data.SqlClient.SqlException
Select Case ex1.Number
Case 17
lblErrors.Text = lblErrors.Text & _
("invalid Server name")
Case 156, 170 'bad SQL syntax
lblErrors.Text = lblErrors.Text & _
("incorrect syntax")
Case 207 'bad field name in select
lblErrors.Text = lblErrors.Text & _
("invalid column name")
Case 208 'bad table name in select
lblErrors.Text = lblErrors.Text & _
("invalid object name")
Case 18452
lblErrors.Text = lblErrors.Text & _
("invalid user name")
Case 18456
lblErrors.Text = lblErrors.Text & _
("invalid password")
Case 4060
lblErrors.Text = lblErrors.Text & _
("invalid database")
End Select
Catch ex2 As System.Exception
lblErrors.Text = lblErrors.Text & _
("Unexpected exception: " & ex2.Message & ". ")
End Try
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 + ". ");
}
31
32
Acceso a datos con Microsoft ADO.NET
El DataAdapter no
puede crear un DataSet
La clase SqlException contiene la excepción que se lanza cuando SQL Server
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
C#
SqlErrorCollection erData = ex1.Errors;
for(int i = 0; i < erData.Count; i++)
{
lblErrors.Text += "Error" + i + ": " +
erData[i].Number + ", " +
erData[i].Class + ", " +
erData[i].Message + "<br>";
}
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.
Nota Para una lista completa de las propiedades de la clase SqlError,
consultar la documentación de Visual Studio .NET.
Acceso a datos con Microsoft ADO.NET
„
33
Números de error de SQL Server
La propiedad Number permite determinar el error específico que se ha
producido. Por ejemplo, la siguiente tabla ofrece una lista de algunos
números de errores SQL Server más habituales y sus descripciones.
„
Número
Descripción
17
Nombre de servidor no válido
4060
Nombre de base de datos no válido
18456
Nombre de usuario o contraseña no válidos
Niveles de gravedad de SQL Server
La siguiente tabla describe niveles de severidad de errores de SQL Server, a
los que se accede a través de la propiedad Class de la clase SqlError.
Gravedad
Descripción
Acción
11-16
Generado por usuario
Puede ser corregido por el usuario.
17-19
Errores de software o
hardware
Podemos seguir trabajando, pero es posible
que no podamos ejecutar una instrucción
determinada. SqlConnection permanece
abierto.
20-25
Errores de software o
hardware
El servidor cierra SqlConnection. El
usuario puede volver a abrir la conexión.
34
Acceso a datos con Microsoft ADO.NET
Lección: utilizar múltiples tablas
„
Almacenar múltiples tablas
„
Crear relaciones
„
Navegar programáticamente entre tablas utilizando
relaciones
„
Navegar visualmente entre tablas utilizando
relaciones
„
Práctica dirigida por el instructor: mostrar datos de
múltiples tablas
*****************************
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
Almacenar múltiples tablas
„
Agregar la primera tabla
daCustomers
daCustomers == New
New SqlDataAdapter
SqlDataAdapter __
("select
("select ** from
from Customers",
Customers", conn1)
conn1)
daCustomers.Fill(ds,
daCustomers.Fill(ds, "Customers")
"Customers")
„
Agregar la(s) siguiente(s) tabla(s)
daOrders
daOrders == New
New SqlDataAdapter
SqlDataAdapter __
("select
*
from
("select * from Orders",
Orders", conn2)
conn2)
daOrders.Fill(ds,
daOrders.Fill(ds, "Orders")
"Orders")
Customers
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
El siguiente código puebla un objeto Customers DataTable utilizando un
objeto DataAdapter denominado daCustomers:
Visual Basic .NET
Dim
Dim
Dim
Dim
conn As SqlConnection
daCustomers As SqlDataAdapter
daOrders As SqlDataAdapter
ds As New DataSet()
'create a connection to the Pubs database
conn = New SqlConnection("data source=localhost;" & _
"integrated security=true;initial catalog=northwind")
'create the first DataTable
daCustomers = New SqlDataAdapter _
("select CustomerID, CompanyName from Customers", conn)
daCustomers.Fill(ds, "Customers")
C#
SqlConnection conn;
SqlDataAdapter daCustomers;
SqlDataAdapter daOrders;
DataSet ds = new DataSet();
// Create a connection to the Pubs database
conn = new SqlConnection("data source=localhost; " +
"integrated security=true;initial catalog=northwind");
// Create the first DataTable
daCustomers = new SqlDataAdapter
("select CustomerID, CompanyName from Customers", conn);
daCustomers.Fill(ds, "Customers");
Agregar tablas
subsiguientes
Después de cargar el primer objeto DataTable, podemos rellenar objetos
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")
C#
// Create the second DataTable
daOrders = new SqlDataAdapter
("select CustomerID, OrderID, OrderDate, ShippedDate " +
"from Orders", conn);
daOrders.Fill(ds, "Orders");
Nota Deberíamos utilizar un nuevo objeto DataAdapter para cada objeto
DataTable de un objeto DataSet.
Acceso a datos con Microsoft ADO.NET
37
Crear relaciones
„
Identificar la columna primaria
Dim
Dim parentCol
parentCol As
As DataColumn
DataColumn == __
ds.Tables("Customers").Columns("CustomerID")
ds.Tables("Customers").Columns("CustomerID")
„
Identificar la columna secundaria
Dim
Dim childCol
childCol As
As DataColumn
DataColumn == __
ds.Tables("Orders").Columns("CustomerID")
ds.Tables("Orders").Columns("CustomerID")
„
Crear DataRelation
parentCol
Dim
Dim dr
dr As
As New
New DataRelation
DataRelation __
("name",
("name", parentCol,
parentCol, __
childCol)
childCol)
ds.DataRelations.Add(dr)
ds.DataRelations.Add(dr)
Tabla Customers
DataSet
DataRelation
childCol
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
Ejemplo de objeto
DataRelation
El siguiente ejemplo crea un objeto DataRelation dr y lo agrega al objeto
DataSet ds:
Visual Basic .NET
'Create DataRelation: each publisher publishes many titles
Dim dr As DataRelation
Dim parentCol As DataColumn
Dim childCol As DataColumn
parentCol = ds.Tables("Customers").Columns("CustomerID")
childCol = ds.Tables("Orders").Columns("CustomerID")
dr = New DataRelation("CustOrders", parentCol, childCol)
ds.Relations.Add(dr)
C#
// Create DataRelation: each publisher publishes many titles
DataRelation dr;
DataColumn parentCol;
DataColumn childCol;
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
Navegar programáticamente entre tablas utilizando relaciones
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");
Orders
Customers
GetChildRows
DataSet
GetParentRow
*****************************
Introducción
En muchos ejemplos de aplicaciones Web, necesitaremos trabajar con datos de
más de una tabla, y a menudo querremos trabajar con datos de tablas
relacionadas. La relación entre una tabla primaria y una tabla secundaria se
denomina relación principal-detalle. Un ejemplo de esta relación sería
recuperar el registro de un cliente y visualizar también información de los
pedidos relacionados con ese cliente.
El modelo de objetos DataSet desconectado nos permite trabajar con múltiples
objetos DataTables en nuestra aplicación Web y definir una relación entre esos
objetos DataTable. Podemos utilizar la relación para navegar por registros
relacionados de las tablas.
Navegar
programáticamente
Una de las principales funciones de una clase DataRelation es permitir la
navegación desde un objeto DataTable a otro objeto DataTable en un objeto
DataSet. Esta capacidad de navegación nos permite recuperar todos los objetos
DataRow relacionados en un objeto DataTable cuando tenemos un único
objeto DataRow de un objeto DataTable relacionado. Por ejemplo, tras
establecer un objeto DataRelation entre un objeto DataTable de clientes y un
objeto DataTable de órdenes de compra, podemos recuperar todas las filas de
los pedidos de un determinado cliente utilizando el método
DataRow.GetChildRows.
El método GetChildRows de un objeto DataRow recupera las filas
relacionadas de un objeto DataTable secundario. El método GetParentRow de
un objeto DataRow recupera la fila primaria de un objeto DataTable primario.
40
Acceso a datos con Microsoft ADO.NET
Por ejemplo, podemos tener un control DataGrid denominado dgCustomers
que muestre datos del objeto DataTable Customers, que es un objeto DataSet
ds. El siguiente código muestra un bucle que recorre todos los registros
childOrder para obtener una lista de números de pedido:
Visual Basic .NET
currentParentRow = ds.Tables("Customers"). _
Rows(dgCustomers.SelectedIndex)
For Each r In currentParentRow.GetChildRows("CustOrders")
Label1.Text &= r("OrderID") & ", "
Next
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
Navegar visualmente entre tablas utilizando relaciones
Dim
Dim tableView
tableView As
As DataView
DataView
Dim
Dim currentRowView
currentRowView As
As DataRowView
DataRowView
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")
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
DataView
DataRowView
Orders
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()
C#
DataView parentTableView = new
DataView(ds.Tables["Customers"]);
DataRowView currentRowView =
parentTableView[dgCustomers.SelectedIndex];
dgChild.DataSource =
currentRowView.CreateChildView("CustOrders");
dgChild.DataBind();
42
Acceso a datos con Microsoft ADO.NET
Práctica dirigida por el instructor: mostrar datos de múltiples tablas
„
Programáticamente:
z
Crear un DataSet
z
Crear un DataRelation
z
„
Mostrar registros secundarios utilizando
DataRelation
Visualmente:
z
Invocar CreateChildView
*****************************
Ë Ejecutar la práctica dirigida por el instructor
1. Abrir la página UseRelations.aspx del proyecto Mod10VB o Mod10CS de
la solución 2310Demos.
2. Generar y examinar la página UseRelations.aspx.
La página tiene dos controles DataGrid. Cuando seleccionamos un cliente
en el primer control DataGrid, el procedimiento de evento lee las filas
relacionadas del objeto DataTable Orders, basándose en la relación y los
números de pedido que se muestran, y genera un DataView para el control
DataGrid secundario.
3. En Visual Studio .NET, visualizar la página de código subyacente de la
página UseRelations.aspx.
4. El procedimiento de evento Page_Load invoca tres sub-procedimientos:
CreateDataSet, MakeDataRelation y BindToDataGrid:
• CreateDataSet. Este sub-procedimiento crea el objeto Connection, el
objeto DataAdapter y el objeto DataSet.
• MakeDataRelation. Este sub-procedimiento crea el objeto
DataRelation entre las dos tablas. La relación es Publishers a Titles.
• BindToDataGrid. Este sub-procedimiento vincula el control DataGrid
a la tabla primaria, Customers.
5. El procedimiento de evento dgParent_SelectedIndexChanged muestra
filas secundarias de dos modos: programáticamente y visualmente:
• Programáticamente. El procedimiento invoca el método GetChildRows
de la fila actual recorre los registros devueltos para mostrar el campo
OrderID de cada fila.
• Visualmente. El procedimiento invoca el método CreateChildView de
la vista de la fila actual y la vincula a un segundo control DataGrid.
Acceso a datos con Microsoft ADO.NET
43
Ë Mostrar el Asistente para formularios de datos
1. Hacer clic con el botón derecho en el proyecto Mod10, clic en Agregar y
clic en Agregar nuevo elemento.
2. En el cuadro de diálogo Agregar nuevo elemento, hacer clic en el
Asistente para formularios de datos en la lista Plantillas, escribir
CustOrders.aspx en el campo Nombre y hacer clic en Abrir.
3. Seguir los pasos del asistente como muestra la siguiente tabla.
En esta página
Hacer lo siguiente
Bienvenido …
Hacer clic en Siguiente.
Escoger el DataSet que deseamos
utilizar
Hacer clic en Crear un nuevo DataSet
denominado, escribir dsCustOrders en
el campo y hacer clic en Siguiente.
Escoger una conexión de datos
Seleccionar una conexión existente a la
base de datos Northwind o crear una
nueva, y hacer clic en Siguiente.
Escoger tablas o vistas
Agregar las tablas Customers y Orders a
la lista Elemento(s) seleccionado(s) y
hacer clic en Siguiente.
Crear una relación entre tablas
Introducir CustOrders en el campo
Nombre, seleccionar Customers como
Tabla primaria, seleccionar Orders
como Tabla secundaria, seleccionar
CustomerID como Clave para ambas
tablas (primaria y secundaria), hacer clic
en el botón > y clic en Siguiente.
Escoger las tablas y columnas a mostrar
Mantener los valores predeterminados
para mostrar todas las columnas en las
tablas Principal y Detalle, y hacer clic
en Finalizar.
El Asistente para formularios de datos crea un formulario Web Form con
un control DataGrid y un botón Load.
4. Hacer clic con el botón derecho en la página CustOrders.aspx del
Explorador de soluciones y hacer clic en Ver en el navegador.
5. En el navegador, hacer clic en Cargar.
El control DataGrid se carga con datos de la tabla Customers y se muestran
los datos.
6. Hacer clic en Mostrar detalles para uno de los clientes y desplazarse hasta
la parte inferior de la página.
La información detallada del cliente seleccionado se muestra en otra tabla.
44
Acceso a datos con Microsoft ADO.NET
Lección: acceder a datos con DataReaders
„
¿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
*****************************
Introducción
La ventaja de utilizar un objeto DataSet es que proporciona una copia
desconectada de la base de datos. Para aplicaciones Web de larga ejecución, el
uso de un objeto DataSet es a menudo la mejor opción. Sin embargo, los
desarrolladores frecuentemente realizan operaciones cortas y sencillas, como
mostrar un único conjunto de datos directamente al usuario o acceder a una
única contraseña, con cada petición de datos. Para ese tipo de operaciones, los
desarrolladores no necesitan mantener un objeto DataSet; pueden utilizar un
objeto DataReader.
En esta sección, aprenderemos a leer datos de una fuente de datos utilizando la
clase DataReader.
Objetivos de la lección
En esta lección, aprenderemos a:
„
Explicar cómo funciona la clase DataReader.
„
Crear un objeto DataReader.
„
Leer datos de un objeto DataReader.
„
Vincular un control de servidor enlazado a lista a un objeto DataReader.
Acceso a datos con Microsoft ADO.NET
45
¿Qué es un DataReader?
„
Sólo hacia delante, sólo lectura
„
Acceso rápido a datos
„
Conexión a una fuente de datos
„
Gestión de la conexión por sí mismo
„
Gestión de los datos por sí mismo, o vincularlos a un
control enlazado a lista
„
Utiliza menos recursos del servidor
*****************************
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
lectura
La clase DataReader proporciona una transferencia de datos de sólo lectura y
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
datos
ADO.NET incluye dos tipos de objetos DataReader: el objeto SqlDataReader
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
Gestión de la conexión
por sí mismo
A diferencia de un objeto DataAdapter que se abre y cierra automáticamente,
debemos gestionar la conexión del objeto DataReader por nosotros mismos.
La clase DataReader se parece a la clase DataAdapter en que creamos un
objeto Command desde una instrucción y una conexión SQL. Sin embargo,
con el objeto DataReader Command, debemos abrir y cerrar explícitamente el
objeto Connection.
Gestión de los datos
uno mismo
Tenemos la opción de recorrer los datos del objeto DataReader y mostrarlo
programáticamente, o podemos vincular un objeto DataReader a un control
enlazado a lista. En ambos casos, debemos escribir el código nosotros mismos.
Utiliza menos recursos
del servidor
Debido a que el DataReader no es una representación en memoria de los datos,
utilizar un DataReader afecta poco a la disponibilidad de los recursos del
servidor.
Acceso a datos con Microsoft ADO.NET
47
Crear un DataReader
„
Para utilizar un DataReader:
11 Crear y abrir la conexión a la base de datos
1.
22 Crear un objeto Command
2.
33 Crear un DataReader desde el objeto Command
3.
44 Invocar el método ExecuteReader
4.
55 Utilizar el objeto DataReader
5.
66 Cerrar el objeto DataReader
6.
77 Cerrar el objeto Connection
7.
„
Utilizar el controlador de errores Try…Catch…Finally
Código de ejemplo
*****************************
Introducción
Para utilizar un objeto SqlDataReader, necesitamos crear un objeto
SqlCommand en lugar de un objeto SqlDataAdapter, que es lo que se
necesitaba con los objetos DataSet. El objeto SqlCommand expone un método
ExecuteReader que devuelve un objeto SqlDataReader.
Similar a un objeto DataAdapter, creamos un objeto Command desde una
instrucción SQL y una conexión. Sin embargo, con el objeto DataReader
Command, debemos explícitamente abrir y cerrar el objeto Connection.
Utilizar un DataReader
Para utilizar un objeto DataReader, debemos codificar manualmente todo el
proceso de conexión. Para utilizar un objeto DataReader se requieren los
siguientes pasos:
1. Crear y abrir la conexión a la base de datos.
2. Crear un objeto Command.
3. Crear el objeto DataReader desde el objeto Command.
4. Invocar el método ExecuteReader.
5. Utilizar el objeto DataReader.
6. Cerrar el objeto DataReader.
7. Cerrar el objeto Connection.
48
Acceso a datos con Microsoft ADO.NET
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()
'create DataReader and display data
Dim dr As SqlDataReader
dr = cmdAuthors.ExecuteReader()
Do While dr.Read()
lstBuiltNames.Items.Add(dr("au_lname") + ", " + _
dr("au_fname"))
Loop
'close DataReader and Connection
dr.Close()
conn.Close()
C#
// Open Connection and create command
SqlConnection conn = new SqlConnection
("data source=localhost; integrated security=true; " +
"initial catalog=pubs;");
SqlCommand cmdAuthors = new SqlCommand
("select * from Authors", conn);
conn.Open();
// Create DataReader and read data
SqlDataReader dr;
dr = cmdAuthors.ExecuteReader();
while (dr.Read())
{
lstBuiltNames.Items.Add(dr["au_lname"] + ", " +
dr["au_fname"]);
}
// Close DataReader and Connection
dr.Close();
conn.Close();
Acceso a datos con Microsoft ADO.NET
Utilizar el controlador de
eventos
Try…Catch…Finally
49
Cuando se utilizan conexiones con el objeto DataReader, debemos utilizar
siempre una instrucción Try…Catch…Finally para garantizar que si algo falla,
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
Leer datos desde un DataReader
„
Invocar Read para cada registro
z
„
Devuelve false cuando no hay más registros
Acceso a campos
z Parámetro es la posición ordinal o nombre del campo
z Las funciones Get ofrecen un mejor rendimiento
Do
Do While
While myReader.Read()
myReader.Read()
str
str &=
&= myReader(1)
myReader(1)
str
str &=
&= myReader("field")
myReader("field")
str
str &=
&= myReader.GetDateTime(2)
myReader.GetDateTime(2)
Loop
Loop
„
Cerrar el DataReader
„
Cerrar la conexión
while
while (myReader.Read())
(myReader.Read())
{{
str
str +=
+= myReader[1];
myReader[1];
str
str +=
+= myReader["field"];
myReader["field"];
str
+=
myReader.GetDateTime(2);
str += myReader.GetDateTime(2);
}}
*****************************
Invocar Read para cada
registro
Tras invocar el método ExecuteReader del objeto Command, podemos
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
Acceso a campos
51
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();
Cerrar la conexión
DataReader no cierra automáticamente la conexión. Debemos invocar
explícitamente el método Close para cerrar la conexión cuando finalicemos su
uso, como muestra el siguiente código de ejemplo:
Visual Basic .NET
conn.Close()
C#
conn.Close();
52
Acceso a datos con Microsoft ADO.NET
Vincular un DataReader a un control enlazado a lista
„
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.DataBind()
dgAuthors.DataBind()
dgAuthors.DataSource
dgAuthors.DataSource == dr;
dr;
dgAuthors.DataBind();
dgAuthors.DataBind();
*****************************
Introducción
Además de recorrer los datos del objeto DataReader y mostrarlos
programáticamente, podemos vincular un objeto DataReader a un control
enlazado a lista.
Para vincular un objeto DataReader a un control enlazado a lista, establecemos
la propiedad DataSource del control enlazado a lista al objeto DataReader. El
siguiente código de ejemplo crea un objeto DataReader dr, lo vincula a un
control ListBox au_lname, y cierra los objetos DataReader y Connection:
Visual Basic .NET
Dim conn As New SqlConnection _
("data source=localhost;integrated security=true;" & _
"initial catalog=pubs")
conn.Open()
Dim cmdAuthors As New SQLCommand _
("select * from Authors", conn)
'bind the datareader to a listbox
Dim dr As SqlDataReader
dr = cmdAuthors.ExecuteReader()
lstBoundNames.DataSource = dr
lstBoundNames.DataTextField = "au_lname"
lstBoundNames.DataBind()
'close the datareader and the connection
dr.Close()
conn.Close()
Acceso a datos con Microsoft ADO.NET
C#
SqlConnection conn = new SqlConnection
("data source=localhost; integrated security=true; " +
"initial catalog=pubs");
conn.Open();
SqlCommand cmdAuthors = new SqlCommand
("select * from Authors", conn);
//bind the datareader to a listbox
SqlDataReader dr;
dr = cmdAuthors.ExecuteReader();
lstBoundNames.DataSource = dr;
lstBoundNames.DataTextField = "au_lname";
lstBoundNames.DataBind();
//close the datareader and the connection
dr.Close();
conn.Close();
53
54
Acceso a datos con Microsoft ADO.NET
Práctica: organizar código para crear un DataReader
„
Los estudiantes:
z
„
Reordenarán líneas de código para crear
un DataReader
Tiempo: 5 minutos
*****************************
En esta práctica, reorganizaremos las líneas de código ADO.NET en el orden
correcto para crear un objeto DataReader.
Ë 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.
Nota Hay varias respuestas correctas para esta práctica.
Acceso a datos con Microsoft ADO.NET
55
Demostración: mostrar datos utilizando DataReaders
„
Crear un objeto SqlConnection
„
Crear un objeto DataReader
„
Vincular el DataReader a un Cuadro de
lista
„
Generar los elementos del Cuadro de
lista a partir de datos proporcionados por
el DataReader
*****************************
Introducción
En esta demostración, examinaremos el código que crea y rellena un objeto
DataReader utilizando un objeto SQLCommand que vincula el objeto
DataReader a un control ListBox, y vuelve a crear el DataReader para
vincularlo a un segundo control ListBox.
Ë 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.
Descargar