• No se han encontrado resultados

Acceso a datos con Microsoft ADO.NET

N/A
N/A
Protected

Academic year: 2018

Share "Acceso a datos con Microsoft ADO.NET"

Copied!
56
0
0

Texto completo

(1)

Í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

(2)

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

*****************************

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.

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.

Introducción

(3)

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

*****************************

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.

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.

Introducción

(4)

Uso de DataSets frente a DataReaders

Soportado por las herramientas de Visual Studio .NET

Acceso más lento

Sólo hacia delante

Vinculado a un único control Basado en una instrucción SQL de una base de datos

Sólo lectura

Codificación manual Acceso más rápido Búsqueda de datos hacia

delante y hacia atrás

Vinculado a múltiples controles Incluye múltiples tablas de distintas bases de datos Acceso lectura/escritura a datos

DataReader DataSet

Desconectado Conectado

*****************************

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 datosvirtual 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.

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

Introducción

(5)

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

(6)

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.

(7)

Lección: conexión a una base de datos

„ Seguridad SQL Server

„ Crear la conexión

„ Demostración: establecer la seguridad SQL Server

*****************************

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. 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.

Introducción

(8)

Seguridad SQL Server

Cliente Cliente

Enviar el nombre de usuario y contraseña

en texto claro.

No enviar el nombre de usuario y contraseña.

Enviar sólo que el usuario ha sido

autenticado. Autenticación modo mixto Autenticación modo mixto Autenticación sólo Windows Autenticación sólo Windows Servidor SQL Sólo la cuenta ASPNET

tiene concedido acceso Servidor SQL Sólo la cuenta ASPNET tiene concedido acceso Servidor Web Autenticación Windows Servidor Web Autenticación Windows o… o… Servidor SQL Cada cuenta de usuario se agrega a grupo login de SQL Server

Servidor SQL Cada cuenta de usuario se agrega a grupo login de SQL Server Servidor Web Configuración ASP.NET predeterminada Servidor Web Configuración ASP.NET predeterminada

Aquí está el nombre de usuario

y la contraseña

*****************************

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.

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:

Dim strConn As String = _ "data source=localhost; " & _ "initial catalog=northwind; " & _ "user id=CohoUser;password=1Coho" Dim conn As New SqlConnection(strConn)

string strConn =

"data source=localhost; " + "initial catalog=northwind; " + "user id=CohoUser; " +

"password=1Coho";

SqlConnection conn = new SqlConnection(strConn);

Introducción

Autenticación En modo mixto

Visual Basic .NET

(9)

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.

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:

Dim strConn As String = _ "data source=localhost; " & _ "initial catalog=northwind; " & _ "integrated security=true"

Dim conn As New SqlConnection(strConn)

string strConn =

"data source=localhost; " + "initial catalog=northwind; " + "integrated security=true";

SqlConnection conn = new SqlConnection(strConn);

Aviso

Autenticación sólo Windows

Visual Basic .NET

(10)

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.

Para más información sobre securizar una aplicación Web, ver el Módulo “Securizar una aplicación Web con Microsoft ASP.NET”.

Configurar el SQL Server para ejecutar autenticación en modo mixto o sólo Windows

(11)

Crear la conexión

„ Uso de SqlConnection

„ Establecer los parámetros de la cadena de conexión

z Timeout de conexión

z Fuente de datos

z Catálogo inicial

z Seguridad integrada

Dim strConn As String = "data source=localhost; " & _ "initial catalog=northwind; integrated security=true" Dim conn As New SqlConnection(strConn)

Dim strConn As String = "data source=localhost; " & _ "initial catalog=northwind; integrated security=true" Dim conn As New SqlConnection(strConn)

z Contraseña

z Persistir información seguridad

z Proveedor

z ID de usuario

string strConn = "data source=localhost; " +

"initial catalog=northwind; integrated security=true"; SqlConnection conn = new SqlConnection(strConn); string strConn = "data source=localhost; " +

"initial catalog=northwind; integrated security=true"; SqlConnection conn = new SqlConnection(strConn);

*****************************

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.

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:

Dim strConn As String = _ "data source=localhost; " & _ "initial catalog=northwind; " & _ "integrated security=true"

Dim conn As New SqlConnection(strConn)

string strConn =

"data source=localhost; " + "initial catalog=northwind; " + "integrated security=true";

SqlConnection conn = new SqlConnection(strConn);

Introducción

Crear una cadena de conexión

Visual Basic .NET

(12)

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.

(13)

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

*****************************

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

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.

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.

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.

Introducción

Abrir SQL Server Enterprise Manager

Establecer el modo de autenticación

(14)

c. En el cuadro de diálogo Propiedades de login de SQL Server, escribir CohoUser en el campo Nombre, hacer clic en AutenticaciónSQL 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.

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 yWindows 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 .

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.

(15)

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

*****************************

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.

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.

Introducción

(16)

Crear un DataAdapter

„ Almacenar la consulta en un DataAdapter

„ El constructor DataAdapter establece la propiedad SelectCommand

„ Establecer las propiedades InsertCommand,

UpdateCommand y DeleteCommand si fuera necesario Dim da As New SqlDataAdapter _

("select * from Authors", conn) Dim da As New SqlDataAdapter _

("select * from Authors", conn)

da.SelectCommand.CommandText da.SelectCommand.Connection da.SelectCommand.CommandText da.SelectCommand.Connection SqlDataAdapter da = new SqlDataAdapter

("select * from Authors",conn); SqlDataAdapter da = new SqlDataAdapter

("select * from Authors",conn);

da.SelectCommand.CommandText; da.SelectCommand.Connection; da.SelectCommand.CommandText; da.SelectCommand.Connection;

*****************************

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.

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.

Introducción

(17)

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.

El siguiente código de ejemplo muestra cómo crear un objeto SqlDataAdapter denominado da que contiene una sentencia de consulta:

'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)

//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);

Propiedades del DataAdapter

Ejemplo de SqlDataAdapter

Visual Basic .NET

(18)

Crear un DataSet

„ Crear y poblar un DataSet con DataTables

z El método Fill ejecuta el SelectCommand

„ Acceder a DataTable

Dim ds As New DataSet() da.Fill(ds, "Authors") Dim ds As New DataSet() da.Fill(ds, "Authors")

Dim r As DataRow Dim str As String For Each r in _

ds.Tables("Authors").Rows str &= r(2)

str &= r("au_lname") Next

Dim r As DataRow Dim str As String For Each r in _

ds.Tables("Authors").Rows str &= r(2)

str &= r("au_lname") Next

ds.Tables("Authors").Rows.Count ds.Tables("Authors").Rows.Count DataSet ds = new DataSet();

da.Fill(ds, "Authors"); DataSet ds = new DataSet(); da.Fill(ds, "Authors");

ds.Tables["Authors"].Rows.Count; ds.Tables["Authors"].Rows.Count;

string str="";

foreach(DataRow r in

ds.Tables["Authors"].Rows) {

str += r[2];

str += r["au_lname"]; }

string str="";

foreach(DataRow r in

ds.Tables["Authors"].Rows) {

str += r[2];

str += r["au_lname"]; }

*****************************

Para crear una copia local de una base de datos, creamos y poblamos un objeto DataSet utilizando objetos DataTable.

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:

Dim ds As New DataSet()

DataSet ds = new 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 DataSetds utilizando un DataAdapter denominado da:

da.Fill(ds, "Authors")

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.

Introducción

Crear a DataSet

Visual Basic .NET

C#

Rellenar el DataSet

Visual Basic .NET

(19)

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 DataSetds.

'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")

//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. 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:

ds.Tables("Authors") -o-

ds.Tables(0)

ds.Tables["Authors"]; -o-

ds.Tables[0];

Visual Basic .NET

C#

Acceder a DataTable

Visual Basic .NET

(20)

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:

Dim col As DataColumn

For Each col In ds.Tables(0).Columns lstItems.Items.Add(col.ColumnName) Next

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:

ds.Tables("Authors").Rows.Count ds.Tables("Authors").Columns.Count

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:

DataSet.Tables(0).Rows(x)(1)

DataSet.Tables(0).Rows(x)("fieldname")

ds.Tables["Authors"].Rows[x][1];

ds.Tables["Authors"].Rows[x]["fieldname"];

Visual Basic .NET

C#

Visual Basic .NET

C#

Visual Basic .NET

(21)

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:

Dim r As DataRow Dim str As String

For Each r in ds.Tables("Authors").Rows str &= r(1)

str &= r("au_lname") Next

string str = "";

foreach(DataRow r in ds.Tables["Authors"].Rows) {

str += r[1];

str += r["au_lname"]; }

Visual Basic .NET

(22)

Demostración: utilizar programáticamente un DataSet

„ Crear una conexión

„ Crear DataAdapter

„ Crear DataSet

„ Leer los datos del DataSet

programáticamente

*****************************

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.

(23)

6. En el procedimiento de evento Page_Load, mostrar el código que crea los siguientes objetos:

SqlConnectionSqlDataAdapterDataSet

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.

(24)

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

„ Establecer una vista distinta de un DataSet

DataView dv = new DataView(ds.Tables["Authors"]); dv.RowFilter = "state = 'CA'";

DataView dv = new DataView(ds.Tables["Authors"]); dv.RowFilter = "state = 'CA'";

Dim dv As DataView = ds.Tables("Authors").DefaultView Dim dv As DataView = ds.Tables("Authors").DefaultView

Dim dv As New DataView (ds.Tables("Authors")) dv.RowFilter = "state = 'CA'"

Dim dv As New DataView (ds.Tables("Authors")) dv.RowFilter = "state = 'CA'"

DataView dv = ds.Tables["Authors"].DefaultView; DataView dv = ds.Tables["Authors"].DefaultView;

*****************************

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.

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. 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 DataViewdv predeterminado, de un objeto DataTable denominado Authors:

Dim dv As DataView = ds.Tables("Authors").DefaultView

DataView dv = ds.Tables["Authors"].DefaultView;

Introducción

DataViews como subconjunto de un DataTable

DefaultView

Visual Basic .NET

(25)

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 DataViewRowFilter 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 DataViewdv, está asignada para recuperar autores únicamente del estado de California y, a continuación, ordenar los resultados por apellido:

Dim dv As New DataView(ds.Tables("Authors")) dv.RowFilter = "state = 'CA'"

dv.Sort = "au_lname"

DataView dv = new DataView(ds.Tables["Authors"]); dv.RowFilter = "state = ‘CA’";

dv.Sort = "au_lname";

DataView personalizado

Visual Basic .NET

(26)

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.

Hay varias respuestas correctas para esta práctica.

(27)

Vincular un DataSet a un control enlazado a lista

„ Crear el control

„ Vincular a un DataSet o un DataView

dg.DataSource = ds dg.DataMember = "Authors" dg.DataBind()

dg.DataSource = ds dg.DataMember = "Authors" dg.DataBind()

<asp:DataGrid id="dg" runat="server" /> <asp:DataGrid id="dg" runat="server" />

dg.DataSource = ds; dg.DataMember = "Authors";

dg.DataBind();

dg.DataSource = ds; dg.DataMember = "Authors"; dg.DataBind();

*****************************

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.

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" />

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:

dg.DataSource = ds

dg.DataMember = "Authors" dg.DataBind()

dg.DataSource = ds;

dg.DataMember = "Authors"; dg.DataBind();

Introducción

Crear el control

Vincular a un Dataset o DataView

Visual Basic .NET

(28)

El siguiente código muestra cómo podemos utilizar también la colección Tables del objeto DataSetds para asignar el objeto DataTableAuthors directamente a la propiedad DataSource del control DataGrid denominado dg:

dg.DataSource = ds.Tables("Authors") dg.DataBind()

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.

El siguiente código de ejemplo muestra cómo vincular un objeto DataViewdv, filtrado para el estado de California, a un control DataGrid dg:

Dim dv As New DataView(ds.Tables("Authors")) dv.RowFilter = "state = 'CA'"

dg.DataSource = dv dg.DataBind()

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.

Visual Basic .NET

C#

Ejemplo de uso de una vista personalizada

Visual Basic .NET

(29)

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

*****************************

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.

(30)

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

*****************************

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.

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:

Introducción

(31)

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

(32)

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 + ". ");

}

(33)

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:

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

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>"; }

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.

Para una lista completa de las propiedades de la clase SqlError, consultar la documentación de Visual Studio .NET.

El DataAdapter no puede crear un DataSet

Visual Basic .NET

C#

Errores de SQL Server

(34)

„ 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

(35)

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

*****************************

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.

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.

Introducción

(36)

Almacenar múltiples tablas

„ Agregar la primera tabla

„ Agregar la(s) siguiente(s) tabla(s)

daCustomers = New SqlDataAdapter _ ("select * from Customers", conn1) daCustomers.Fill(ds, "Customers")

daCustomers = New SqlDataAdapter _ ("select * from Customers", conn1) daCustomers.Fill(ds, "Customers")

Orders Customers daOrders = New SqlDataAdapter _

("select * from Orders", conn2) daOrders.Fill(ds, "Orders")

daOrders = New SqlDataAdapter _ ("select * from Orders", conn2) daOrders.Fill(ds, "Orders")

conn2 conn1

DataSet

*****************************

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.

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.

Introducción

(37)

El siguiente código puebla un objeto CustomersDataTable utilizando un objeto DataAdapter denominado daCustomers:

Dim conn As SqlConnection

Dim daCustomers As SqlDataAdapter Dim daOrders As SqlDataAdapter Dim 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")

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");

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 OrdersDataTable.

El siguiente código puebla el objeto OrdersDataTable utilizando un objeto DataAdapter denominado daOrders:

'Create the second DataTable daOrders = New SqlDataAdapter _

("select CustomerID, OrderID, OrderDate, ShippedDate " & _ "from Orders", conn)

daOrders.Fill(ds, "Orders")

// Create the second DataTable daOrders = new SqlDataAdapter

("select CustomerID, OrderID, OrderDate, ShippedDate " + "from Orders", conn);

daOrders.Fill(ds, "Orders");

Deberíamos utilizar un nuevo objeto DataAdapter para cada objeto DataTable de un objeto DataSet.

Visual Basic .NET

C#

Agregar tablas subsiguientes

Visual Basic .NET

C#

(38)

Crear relaciones

„ Identificar la columna primaria

„ Identificar la columna secundaria

„ Crear DataRelation

Dim dr As New DataRelation _ ("name", parentCol, _ childCol)

ds.DataRelations.Add(dr)

Dim dr As New DataRelation _ ("name", parentCol, _ childCol)

ds.DataRelations.Add(dr)

Dim parentCol As DataColumn = _

ds.Tables("Customers").Columns("CustomerID")

Dim parentCol As DataColumn = _

ds.Tables("Customers").Columns("CustomerID")

Dim childCol As DataColumn = _

ds.Tables("Orders").Columns("CustomerID")

Dim childCol As DataColumn = _

ds.Tables("Orders").Columns("CustomerID")

Tabla Orders Tabla Customers

DataSet

parentCol

childCol DataRelation

Código de ejemplo C#

*****************************

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.

(39)

El siguiente ejemplo crea un objeto DataRelationdr y lo agrega al objeto DataSetds:

'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)

// 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);

Para más información sobre relaciones de datos, ver “Explorar una relación entre tablas,” en la documentación de Visual Studio .NET.

Ejemplo de objeto DataRelation

Visual Basic .NET

C#

(40)

Navegar programáticamente entre tablas utilizando relaciones

ds.Tables(index).Rows(index).GetChildRows("relation") ds.Tables(index).Rows(index).GetParentRow("relation")

ds.Tables(index).Rows(index).GetChildRows("relation")

ds.Tables(index).Rows(index).GetParentRow("relation")

Customers Orders GetChildRows

GetParentRow DataSet

ds.Tables[index].Rows[index].GetChildRows("relation"); ds.Tables[index].Rows[index].GetParentRow("relation");

ds.Tables[index].Rows[index].GetChildRows("relation");

ds.Tables[index].Rows[index].GetParentRow("relation");

*****************************

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.

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.

Introducción

Navegar

(41)

Por ejemplo, podemos tener un control DataGrid denominado dgCustomers que muestre datos del objeto DataTableCustomers, 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:

currentParentRow = ds.Tables("Customers"). _ Rows(dgCustomers.SelectedIndex)

For Each r In currentParentRow.GetChildRows("CustOrders") Label1.Text &= r("OrderID") & ", "

Next

currentParentRow = ds.Tables["Customers"]. Rows[dgCustomers.SelectedIndex];

foreach(DataRow r

in currentParentRow.GetChildRows("CustOrders")) {

Label1.Text += r["OrderID"] + ","; }

Visual Basic .NET

(42)

Navegar visualmente entre tablas utilizando relaciones

Dim tableView As DataView

Dim currentRowView As DataRowView

tableView = New DataView(ds.Tables("Customers")) currentRowView = tableView(dgCustomers.SelectedIndex)

dgChild.DataSource = currentRowView.CreateChildView("CustOrders") Dim tableView As DataView

Dim currentRowView As DataRowView

tableView = New DataView(ds.Tables("Customers")) currentRowView = tableView(dgCustomers.SelectedIndex)

dgChild.DataSource = currentRowView.CreateChildView("CustOrders")

Customers Orders CreateChildView DataRowView DataView DataSet DataView tableView; DataRowView currentRowView;

tableView = new DataView(ds.Tables["Customers"]); currentRowView = tableView[dgCustomers.SelectedIndex];

dgChild.DataSource = currentRowView.CreateChildView("CustOrders"); DataView tableView;

DataRowView currentRowView;

tableView = new DataView(ds.Tables["Customers"]); currentRowView = tableView[dgCustomers.SelectedIndex];

dgChild.DataSource = currentRowView.CreateChildView("CustOrders");

*****************************

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:

Dim parentTableView As New _

DataView(ds.Tables("Customers")) Dim currentRowView As DataRowView = _

parentTableView(dgCustomers.SelectedIndex) dgChild.DataSource = _

currentRowView.CreateChildView("CustOrders") dgChild.DataBind()

DataView parentTableView = new

DataView(ds.Tables["Customers"]); DataRowView currentRowView =

parentTableView[dgCustomers.SelectedIndex];

dgChild.DataSource =

currentRowView.CreateChildView("CustOrders"); dgChild.DataBind();

Navegar visualmente

Visual Basic .NET

(43)

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.

Referencias

Documento similar

En un congrés, convé disposar d’un pla o full de ruta per tal de garantir la igualtat d’accés de totes les persones, tant ponents com participants.. Comunicació : Tant si el

En cada antecedente debe considerarse como mínimo: Autor, Nombre de la Investigación, año de la investigación, objetivo, metodología de la investigación,

Al no observar una significante relación con el valor de p=0,165 (p&gt;0,05) y correlación muy baja de r=0,071, se considera que no existe relación significativa entre

Firmaron, por parte de GRANTECAN, Pascual Fernández Martínez, Presidente del Consejo de Administración y Director General de Análisis y Programación Presupuestaria del Ministerio

En este proyecto se utiliza para la implementaci´ on de la base de datos tanto para los usuarios del sistema como para los dispositivos asociados a dichos usuarios.. Adem´ as,

1 PRETENDE Diego de Silua Velazquez, que se han de mandar boluer a la Camara los papeles de la merced que su Magestad tiene hecha del oficio de Escriuano del Respeto mayor

La principal implicaci´on del an´alisis impulso–respuesta para la volatilidad que hemos llevado a cabo es que el mecanismo de transmisi´on de la volatilidad desde el tipo de inter´es

Para ello se colocarán dos sensores de presión a distintas alturas, uno ubicado en la parte superior (sin contacto con el agua) y otro ubicado en el mínimo nivel de