Vous êtes sur la page 1sur 24

ACCESO A BASE DE

DATOS CON
ADO.NET

logos Conocimiento, S.L. Madrid 2009. Todos los derechos de Propiedad Intelectual e Industrial de esta obra pertenecen a logos Conocimiento, S.L.

NDICE
ACCESO A BASE DE DATOS CON ADO.NET

6. ACCESO A DATOS EN MODO DESCONECTADO


6.1 Caractersticas del acceso a datos en modo desconectado. . . . . . . . . . . . . . . . . . . . .3
6.2 Creacin de DataSets y DataTables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6
6.3 Recorrido y manipulacin de datos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10
6.4 Actualizacin de un DataSet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .14
6.5 Relaciones entre tablas DataRelation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .19
6.6 Filtrado de datos DataView. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .20

ACCESO A BASE DE DATOS CON ADO.NET


6.1 Caractersticas del acceso a datos en modo desconectado.
Volvemos a vernos, parece que te ha gustado esto, espero que siga as la cosa.
Ahora vamos a volcarnos en el modo ms habitual de acceso a datos, es decir, el modo desconectado.
Como ya comentamos al principio de este tema sobre acceso a datos, este es el tipo de acceso ms habitual
cuando has de trabajar con los datos y efectuar modificaciones en la base de datos. Ya que te permite
recuperar la informacin necesaria, desconectarte de la base de datos, con lo que no ocupas ancho de banda,
recursos del servidor ni bloqueas la base de datos, trabajar en local con los datos recuperados y volcar
finalmente a la base de datos todos los cambios aportados.
Todo ello con los correspondientes controles y validaciones previas en cuanto a la situacin de loa informacin
en la base de datos antes de efectuar las inserciones, sustituciones o eliminaciones, para tener en cuenta
todo lo que hayan podido hacer el resto de usuarios del sistema.
Te vuelvo a refrescar el cuadro resumen de los modos de conexin.

Evidentemente, ahora vamos a cambiar la zona en la que nos vamos a centrar,


y pasaremos al apartado del DataAdapter y DataSet.

ACCESO A BASE DE DATOS CON ADO.NET


No te preocupes, no va a ser tan grave como parece a simple vista.
En la programacin tradicional, se utilizaba la conexin permanente a la base de datos, principalmente por
dos motivos.
El primero era que no se dispona de muchas ms tecnologas para hacerlo. Siempre se poda uno inventar
el sistema que actualmente implementan los propios gestores de bases de datos o el ADO.NET en cuanto a
la verificacin previa de que los datos en la base siguen como estaban al cogerlos, para evitar inconsistencias,
pero era largo y tedioso y normalmente el esfuerzo no vala la pena, entre otras por:
El segundo motivo era que, normalmente, no haca falta tener en cuenta los problemas de bloqueos, ya que
los usuarios entraban prcticamente de uno en uno, ni de ancho de banda, ya que no se acceda por
comunicaciones, ni casi de rendimiento del sistema por estar estos casi dedicados a esa tarea.
Pero esos tiempos han pasado a la prehistoria ya.
Hoy en da, en las empresas hay una enorme cantidad de empleados accediendo simultneamente a las bases
de datos, normalmente por algn medio de comunicacin, al estar los sistemas descentralizados, cuanto
menos en granjas de servidores, y al ser el rendimiento de los sistemas una cuestin siempre en el filo de la
navaja. Entre otras debido al enorme consumo de recursos que pueden llegar a implicar algunas de las
operaciones actualmente disponibles.
Por lo tanto, ya hace bastante tiempo que se han desarrollado, casi a la par que los actuales sistemas gestores
de bases de datos relacionales, unas herramientas que permitan que los usuarios realicen cuantas ms
operaciones desconectados de la base de datos, mejor.
Para ello se han implementado, en los motores de las bases de datos, unos sistemas de marcado de registros
para saber el momento exacto, a la centsima de segundo, en el que se ha realizado el ltimo cambio a los
mismos. Con estas marcas de verificacin, los sistemas de acceso a datos, como pueda ser ADO.NET, tienen
mucho ms fcil la verificacin de la situacin de la informacin.
Adems de estas marcas, para toda aquella informacin sensible, se han montado unos sistemas de auditora
de cambios que reflejan qu ha cambiado en cada operacin de cambio y quin lo realiz. De esta forma,
un registro que figure como cambiado, puede llegar a ser actualizado por otro proceso, siempre que la
informacin cambiado no sea la misma, lgicamente. Bueno, tambin hay excepciones a esto, pero tampoco
vamos a entrar ahora en temas de concurrencia optimista o pesimista, baste saber que, en caso necesario,
estn previstos unos mecanismos de sobre-escritura de la informacin en funcin de prioridades de procesos
y/o usuario.

ACCESO A BASE DE DATOS CON ADO.NET


Pero para que todo esto funcione adecuadamente, los sistemas, como ADO.NET, deben recuperar no slo los
registros solicitados por el proceso, sino tambin todo lo relativo a relaciones entre tablas y restricciones,
que son las limitaciones a adiciones o supresiones establecidas por las relaciones de dependencia con otras
tablas o ndices.
Estas metodologas desconectadas permiten que los procesos trabajen con un conjunto coherente de datos
proveniente, a veces, de distintos orgenes de datos, incluso informacin local o de origen XML. Todo esto
ser transparente al proceso y al usuario, que utilizarn la informacin como un todo. Ya ser tarea posterior
de la implementacin el efectuar las actualizaciones coordinadas de todos los orgenes de datos.
Con ADO.NET la recuperacin de la informacin se efecta, normalmente, contra un DataSet, como ya hemos
comentado, y esto permite separar el cdigo para el acceso y recuperacin de los datos del correspondiente
a la presentacin y a la manipulacin de los mismos. Recuerdas las capas de abstraccin?
Es decir, puedes tener unos procesos especficamente encargados de la recuperacin de la informacin,
venga de donde venga y de la elaboracin del DataSet.
Despus desarrollars otros procesos que se encargarn de la presentacin de la misma al usuario, en funcin
de su plataforma o dispositivo de acceso.
Y, finalmente, tendrs otros procesos que sern los encargados de ejecutar, con esos datos, las operaciones
que indique el usuario.
De esta forma, de la gestin de los accesos a los orgenes de datos y proceso de carga y actualizacin de los
datos se encargar una parte que no tiene porqu tener nada que ver con el cmo acceder el usuario.
De la misma forma, los procesos que gestionen el aspecto visual de tus aplicaciones no tienen porqu conocer
los algoritmos de clculo concretos que se han de utilizar para efectuar alguna de las operaciones disponibles
con los datos.
De eso ya se encargarn los procesos especficos de negocio, los cuales coordinarn la gestin y ejecucin
de los otros, en funcin de las necesidades y accesos producidos.

ACCESO A BASE DE DATOS CON ADO.NET


6.2 Creacin de DataSets y DataTables.
Como ya hemos comentado, para la gestin desconectada de los datos ADO.NET nos suministra los DataSet,
que son unos objetos especficamente diseados para proveernos de una especie de copia fantasma de los
datos, con la estructura que le indiquemos, para poder trabajar en local con ellos.
Vengan de donde vengan y sea cual sea la estructura que tengan en origen. Con una ventaja aadida,
podemos construir en local un DataSet con informacin de distintos orgenes, coordinarla y elaborarla
adecuadamente y luego generar un esquema XML, por ejemplo, para transmitirlo a otro sistema, compatible
con XML para su recuperacin y lectura.
Dentro de nuestro DataSet dispondremos de unas colecciones de objetos que nos harn la vida ms fcil, al
menos a los desarrolladores.
Estos son:
- DataTableCollection: una coleccin de objetos DataTable, que contendrn los datos.
- DataRelationCollection: una coleccin de objetos DataRelation que contendr las relaciones entre
las diferentes DataTables de nuestro DataSet.
Los objetos DataTable, a su vez, estn compuestos por las siguientes colecciones:
- DataRowCollection: que es la coleccin de registros que componen la tabla.
- DataColumnCollection: que son la identificacin de los datos que componen cada registro.
- ConstraintCollection: que son las posibles restricciones que se imponen a la hora de aadir o eliminar
registros, por dependencia de otras tablas.
Tanto los Dataset como los DataTable son independientes del proveedor de datos, por lo que no tendrs
SqlDataSet, por ejemplo.
En cambio, los DataAdapter desde los que se rellenan stos, s que son especficos por proveedor, por lo que
si tendrs SqlDataAdapter.
Para crear un nuevo DataSet es tan sencillo como lo siguiente:
Dim DataSetPrueba As DataSet = New DataSet(Prueba)
Siendo el valor entre comillas del New el nombre del DataSet.
En cambio para rellenar ste DataSet y crear sus correspondientes DataTable, vamos a necesitar crear antes
un DataAdapter, especfico para nuestro proveedor de datos y que sea el encargado de recuperar los datos
del mismo y suminstraselos al DataSet.

ACCESO A BASE DE DATOS CON ADO.NET


Un DataAdapter puede contener las propiedades: SelectCommand, InsertCommand, UpdateCommand,
DeleteCommand y TableMappings que son los comandos especficos y especializados para recuperar datos,
aadir nuevos registros, modificar los datos existentes, suprimir registros y la correlacin de tablas y
columnas del origen de datos, respectivamente.
El DataAdapter pasar los datos al DataSet mediante su mtodo Fill, y los pasar hacia el origen de datos
mediante su mtodo Update.
La secuencia de creacin, carga de datos y llenado del DataSet desde un DataAdapter sera, ms o menos,
como sigue:
a) Crear la conexin.
b) Crear el DataAdapter.
c) Aadir un TableMappings a la coleccin del DataAdapter.
d) Crear el comando con su sentencia de lectura de datos.
e) Asignarlo a la propiedad SelectCommand del DataAdapter.
f) Abrir la conexin.
g) Llamar al mtodo Fill del DataAdapter, indicndole el DataSet de destino.
h) Cerrar la conexin.
Como puedes comprobar, con este mtodo, el tiempo que la conexin permanece abierta es mnimo y cuando
la secuencia de operaciones previas es muy larga, esto empieza a revestir su importancia.
Para variar, vamos a ver un pequeo ejemplo de todo esto en accin te parece? Aunque si ya ests saturado,
siempre te lo puedes saltar.

Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Transactions
Module Module1
Dim connectionString As String
Public Sub Main()
Aqu definimos la cadena de conexin
connectionString = Data Source=LG-TONY\SQLEXPRESS2008;Initial
Catalog=AdventureWorks;Integrated Security=SSPI;

ACCESO A BASE DE DATOS CON ADO.NET


desconectado()
End Sub
Public Sub desconectado()
Using connection As New SqlConnection(connectionString)
Creamos el DataAdapter
Dim ProductDA As SqlDataAdapter = New SqlDataAdapter()
Le asignamos la tabla de la que deseamos recuperar
informacin
ProductDA.TableMappings.Add(Table, Production.Product)
Definimos el SelectCommand que vamos a utilizar
Como puedes comprobar, en este caso te he puesto la
definicin en una sola lnea
Dim ProductSC As SqlCommand = New SqlCommand(SELECT ProductID, Name,
ProductModelID FROM Production.Product;, connection)
ProductSC.CommandType = CommandType.Text
Asignamos el comando recin creado al DataAdapter
ProductDA.SelectCommand = ProductSC
Creamos el DataSet
Dim DataSetPrueba As DataSet = New DataSet(Prueba)
Se abre la conexin
connection.Open()
Console.WriteLine(Establecida la conexin)
Llenamos el DataSet
ProductDA.Fill(DataSetPrueba)
Cerramos la conexin
connection.Close()
Console.WriteLine(Conexin cerrada)
Contamos cuantos registros se ha traido
Dim cuenta As Integer =
DataSetPrueba.Tables(Production.Product).Rows.Count()
Console.WriteLine(Ha leido: & cuenta & _
registros de la base de datos para la tabla Product)
Como siempre, para que puedas leer lo escrito
Console.ReadLine()
End Using
End Sub

ACCESO A BASE DE DATOS CON ADO.NET


Y, como siempre, pulsando F5.

Como ves, es bastante fcil de comprender el sistema, una vez que te lo han explicado, claro.

ACCESO A BASE DE DATOS CON ADO.NET


6.3 Recorrido y manipulacin de datos.
Bueno, pues una vez visto como conectar a la base de datos y rellenar una tabla de un DataSet mediante un
DataAdapter, habr que ir un paso ms all y hacer algo con esos datos no? Pues a ello.
Lo primero sera recorrer los registros ledos no te parece?, pues es bastante sencillo, echa una ojeada al
ejemplo y vers.

Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Transactions
Module Module1
Dim connectionString As String
Public Sub Main()
Aqu definimos la cadena de conexin
connectionString = Data Source=LG-TONY\SQLEXPRESS2008; & _
Initial Catalog=AdventureWorks; & _
Integrated Security=SSPI;
desconectado()
End Sub
Public Sub desconectado()
Using connection As New SqlConnection(connectionString)
Creamos el DataAdapter
Dim ProductDA As SqlDataAdapter = New SqlDataAdapter()
Le asignamos la tabla de la que deseamos recuperar informacin
ProductDA.TableMappings.Add(Table, Production.Product)
Definimos el SelectCommand que vamos a utilizar
Dim sql1 As String = SELECT ProductID, Name, & _
ProductModelID FROM Production.Product
Dim sql2 As String = WHERE ProductModelID > 0;
Dim sql As String = sql1 & sql2
Dim ProductSC As SqlCommand = New SqlCommand(sql, connection)
ProductSC.CommandType = CommandType.Text
Asignamos el comando recin creado al DataAdapter
ProductDA.SelectCommand = ProductSC
Creamos el DataSet
Dim DataSetPrueba As DataSet = New DataSet(Prueba)
Se abre la conexin
connection.Open()

10

ACCESO A BASE DE DATOS CON ADO.NET


Console.WriteLine(Establecida la conexin)
Llenamos el DataSet
ProductDA.Fill(DataSetPrueba)
Cerramos la conexin
connection.Close()
Console.WriteLine(Conexin cerrada)
Contamos cuantos registros se ha traido
Dim cuenta As Integer =
DataSetPrueba.Tables(Production.Product).Rows.Count()
Console.WriteLine(Ha leido: & cuenta & _
registros de la base de datos para la tabla Product)
Pasamos a recorer los 10 primeros editando su
informacin
Dim i As Integer = 0
Console.WriteLine(Ahora mostraremos el contenido de &_
los 10 primeros ledos)
Console.WriteLine(ProductID & vbTab & Name & _
vbTab & vbTab & vbTab & ProductModelId)
For Each fila As DataRow In
DataSetPrueba.Tables(Production.Product).Rows
Esta apa es para intentar cuadrar los campos en columnas
If (fila.Field(Of String)(1).Length() > 24) Then
Console.WriteLine(fila.Field(Of Integer)(0).ToString() & vbTab & _
fila.Field(Of String)(1) & vbTab & _
fila.Field(Of Integer)(2).ToString())
Else
Console.WriteLine(fila.Field(Of Integer)(0).ToString() & vbTab & _
fila.Field(Of String)(1) & vbTab & vbTab & _
fila.Field(Of Integer)(2).ToString())
End If
i += 1
If (i >= 10) Then
Exit For
End If
Next
Como siempre, para que puedas leer lo escrito
Console.ReadLine()
End Using
End Sub
End Module

11

ACCESO A BASE DE DATOS CON ADO.NET

Como ves, no ha funcionado del todo, hay un registro con el nombre demasiado corto y no quera
meter ms condiciones en el If.
Para recorrer los datos de un DataTable de un DataSet no es preciso el ForEach de toda la coleccin de Rows
de la misma, hay otros mtodos, menos manuales para hacerlo, aunque si lo que necesitas es pasar por
todos los registros, esta es una estupenda herramienta.
Pero claro, no siempre nos interesa tratar todo lo que se haya trado el DataAdapter, a veces hay que filtrar
la informacin de un modo que no se poda realizar con la sentencia Select del comando, pues para eso
disponemos del mtodo Select del objeto DataTable, el cual nos permite asimismo ordenar los resultados.
Tambin tenemos el mtodo Find de la coleccin DataRowCollection para hallar registros por clave.
Aunque suele dar mejor rendimiento la utilizacin de un DataView (que veremos ms adelante) para el tema
de filtros y ordenaciones sobre un DataTable que el uso de Select, pero dispones de ambas herramientas.
El mtodo Select dispone de otra forma de seleccionar los registros del DataTable, es mediante el filtro de
la propiedad DataViewRowState, que registra el estado de la fila con respecto a la situacin inicial de la
carga, con un amplio espectro de situaciones que nos permiten un sistema de filtrado diferente y muy
potente.

12

ACCESO A BASE DE DATOS CON ADO.NET


Has de saber que el mtodo Select utiliza 3 parmetros, uno por tipo de filtrado, con lo que se pueden
combinar de la forma que se deseen. Es decir, puedes hacer un filtro de registros, darles una ordenacin
especial y que se tengan en cuenta slo aquellos que se hayan aadido, por ejemplo.
En cambio, un DataView es un objeto especializado en ordenar, filtrar, hacer bsquedas, editar y navegar por
los registros de un DataTable, especialmente orientado a su enlace con controles de formularios Windows y
Web de presentacin de datos.
Te sorprender lo de edicin, pero es que tiene unos mtodos de AddNew y Delete que lo permiten, con lo
cul te facilita el trabajo con el contenido del DataTable, sobre todo si operas en l mediante un control de
formulario, en el que tendrs la representacin visual y la opcin de actuar directamente sobre el o los
registros que te interesen.

13

ACCESO A BASE DE DATOS CON ADO.NET


6.4 Actualizacin de un DataSet.
Una obviedad, pero que a veces se olvida, por muchos que lancemos operaciones de actualizacin de datos
de forma masiva, por ejemplo la insercin de 10 registros o el borrado de media tabla o la actualizacin de
todos los clientes que tengan un determinado cdigo postal, todas estas operaciones se realizan realmente
fila a fila, es decir, cada operacin trata, en un momento dado, un nico DataRow de uno de los DataTable
incluidos en el DataSet, que es por lo que este objeto tiene todas las propiedades y mtodos necesarios para
operar sobre las filas de datos.
Por otra parte, en los DataSet se conservan siempre las distintas versiones de cada fila de datos, es decir,
tal y como se trajo de la base de datos, si ha sufrido alguna modificacin, si ha sido suprimida o si ha sido
aadida al conjunto. Todo esto de cara a facilitar la posterior actualizacin de la informacin en la base de
datos.
Para aadir un registro debes, primero, crear un registro vaco del tipo del DataTable que te interese, despus
asignar valor a todos aquellos campos requeridos o que no tengan valor por defecto y luego utilizar el mtodo
Add de la coleccin Rows del DataTable. O generar directamente un nuevo registro en el DataTable, mediante
su mtodo NewRow, e ir asignando el valor a cada uno de los campos del registro resultante. Finalmente,
ejecutaremos el mtodo Add de la coleccin Rows del DataTable para incorporarla a la misma.
Para eliminar un registro tienes dos posibilidades, marcar el registro para borrado posterior en la base de
datos, mtodo Delete del DataRow, si es suprimir el registro de datos locales, entonces el mtodo Remove
de la coleccin de Rows del DataTable.
En ambos casos, antes de eliminar o suprimir el registro, debers encontrarlo, es decir localizar el registro
concreto y obtener un objeto DataRow para actuar sobre l. Para ello puedes utilizar el mtodo Select de
DataTable indicando mediante una condicin SQL, los datos necesarios para hallar el registro o registros que
te interesen. Esta operacin devuelve una matriz de filas, por lo que habrs de operar con ndice sobre el
resultado de la operacin.
Para modificar registros debers, primero, efectuar lo mismo que para la eliminacin, encontrar el registro
o registros que deseas cambiar. Una vez cargados en la matriz de DataRows, ya podrs ir actuando
individualmente sobre ellos.
Evidentemente, todas estas operaciones se efectuarn de esta forma cuando estemos trabajando desde
cdigo, cuando veamos los enlaces a controles de formularios vers que la mayora de ellas quedan implcitas
en la gestin del control, con lo que no necesitars realizar prcticamente nada por tu cuenta en el cdigo.
Una vez vista la forma de operar con los datos contenidos en el DataSet, habr que ver cmo se repercuten
a la base de datos.

14

ACCESO A BASE DE DATOS CON ADO.NET


La forma fcil es utilizar el mtodo Update del DataAdapter, as se replican directamente todos los cambios
tal cual a la base de datos, pero no ofrece un control fino sobre la forma de aplicarse estos cambios.
De primeras, se recorrer todos los registros y uno por uno intentar aplicar los cambios producidos, si no
hay cambios, no har nada ms, pero ha perdido el tiempo de comprobarlo, disponiendo, como dispone, de
un mtodo GetChanges() que devuelve directamente el conjunto de registros en los que se efectu algn
cambio, adicin, modificacin o eliminacin.
Con este mtodo, de momento, ya estaremos tratando muchos menos registros, lo cual redundar en el
rendimiento del sistema.
Otro control, an ms fino, es el de recuperar los cambios efectuados de forma ordenada, es decir, recoger
primero las adiciones y aplicarlas a la base de datos, despus recuperar slo las eliminaciones y aplicarlas y,
finalmente, recuperar las modificaciones efectuadas y realizarlas contra la base de datos.
Parece muy pesado, pero en realidad son muy pocas lneas de cdigo ms, y te dan a cambio un gran control
sobre lo que ests efectuando.
Despus de haber replicado los cambios en la base de datos, necesitars confirmarlos en el propio DataSet.
Para hacerlo necesitars emplear el mtodo AcceptChanges(), el cul dejar slo las versiones finales de los
registros, eliminar los borrados y dejar todo con la situacin de recin cargado de la base de datos. Viene
a ser equivalente a volver a cargarlo todo, pero sin tener que establecer una nueva conexin ni implicar
trfico de datos.
Ahora toca el correspondiente ejemplo, para ver en accin alguna de las cosas aqu explicadas preparado?

Imports
Imports
Imports
Imports

System
System.Data
System.Data.SqlClient
System.Transactions

Module Module1
Dim connectionString As String
Public Sub Main()
Aqu definimos la cadena de conexin
connectionString = Data Source=LG-TONY\SQLEXPRESS2008; & _
Initial Catalog=AdventureWorks;Integrated Security=SSPI;
adicion()
End Sub

15

ACCESO A BASE DE DATOS CON ADO.NET

Public Sub adicion()


Creamos el DataSet
Dim Datos As DataSet = New DataSet()
Datos = CargarDatos()
Contamos cuantos registros se ha traido
Dim cuenta As Integer = Datos.Tables(Production.Product).Rows.Count()
Console.WriteLine(Ha leido: & cuenta & _
registros de la base de datos para la tabla Product)
Mostramos la tabla cargada
Mostrar(Datos.Tables(Production.Product), Tabla original)
Cambiamos algn dato
Datos.Tables(Production.Product).Rows(0)(Name) = Primer registro
Datos.Tables(Production.Product).Rows(1)(name) = Segundo registro
Mostrar(Datos.Tables(Production.Product).GetChanges(), Cambios efectuados)
Aadimos un registro a la segunda vista
Dim fila As DataRow
fila = Datos.Tables(Production.Product).NewRow
fila(ProductID) = 123
fila(Name) = Prueba de nuevo registro
fila(ProductModelID) = 33
Datos.Tables(Production.Product).Rows.Add(fila)
Mostrar(Datos.Tables(Production.Product).GetChanges(DataRowState.Added Or
DataRowState.Modified), Registros aadidos o modificados)
End Sub
Public Function CargarDatos() As DataSet
Creamos el DataSet
Dim Datos As DataSet = New DataSet(Prueba)
Using connection As New SqlConnection(connectionString)
Creamos el DataAdapter
Dim ProductDA As SqlDataAdapter = New SqlDataAdapter()
Le asignamos la tabla de la que deseamos recuperar informacin
ProductDA.TableMappings.Add(Table, Production.Product)
Definimos el SelectCommand que vamos a utilizar
Dim sql1 As String = SELECT ProductID, Name, ProductModelID & _
FROM Production.Product

16

ACCESO A BASE DE DATOS CON ADO.NET


Dim sql2 As String = WHERE ProductModelID > 0;
Dim sql As String = sql1 & sql2
Dim ProductSC As SqlCommand = New SqlCommand(sql, connection)
ProductSC.CommandType = CommandType.Text
Asignamos el comando recin creado al DataAdapter
ProductDA.SelectCommand = ProductSC
Se abre la conexin
connection.Open()
Console.WriteLine(Establecida la conexin)
Llenamos el DataSet
ProductDA.Fill(Datos)
Cerramos la conexin
connection.Close()
Console.WriteLine(Conexin cerrada)
End Using
Return (Datos)
End Function
Public Sub Mostrar(ByVal Tabla As DataTable, ByVal Etiqueta As String)
Console.WriteLine(Ahora mostraremos el contenido de los 10 primeros & _
registros de & Etiqueta)
If Tabla.Rows.Count > 0 Then
Dim i As Integer = 0
Console.WriteLine(ProductID & vbTab & Name & vbTab & vbTab & _
vbTab & ProductModelId)
For Each fila As DataRow In Tabla.Rows
If (fila.Field(Of String)(1).Length() > 24) Then
Console.WriteLine(fila.Field(Of Integer)(0).ToString() & vbTab & _
fila.Field(Of String)(1) & vbTab & _
fila.Field(Of Integer)(2).ToString())
Else
Console.WriteLine(fila.Field(Of Integer)(0).ToString() & vbTab & _
fila.Field(Of String)(1) & vbTab & vbTab & _
fila.Field(Of Integer)(2).ToString())
End If
i += 1

17

ACCESO A BASE DE DATOS CON ADO.NET


If (i >= 10) Then
Exit For
End If
Next
Else
Console.WriteLine(No hay registros en & Etiqueta)
End If
Console.ReadLine()
End Sub
Public Sub Mostrar(ByVal Vista As DataView, ByVal Etiqueta As String)
Console.WriteLine(Ahora mostraremos el contenido de los 10 primeros & _
registros de & Etiqueta)
If Vista.Count > 0 Then
Console.WriteLine(ProductID & vbTab & Name & vbTab & ProductModelId)
For i As Integer = 0 To 10
Console.WriteLine(Vista(i).Row.Field(Of Integer)(0).ToString() & _
vbTab & Vista(i).Row.Field(Of String)(1) & vbTab & _
Vista(i).Row.Field(Of Integer)(2).ToString())
If i >= Vista.Count - 1 Then
Exit For
End If
Next i
Else
Console.WriteLine(No hay registros en & Etiqueta)
End If
Console.ReadLine()
End Sub
End Module

Como ves es bastante fcil de seguir. Dejando al margen el tema del desglose en diversas rutinas
y funciones del cdigo, aunque a estas alturas ya no debera suponer ningn problema para ti.

18

ACCESO A BASE DE DATOS CON ADO.NET


6.5 Relaciones entre tablas DataRelation.
Normalmente entre las tablas de una base de datos hay unas relaciones establecidas, basadas en las
dependencias de clave entre ellas.
Es decir, normalmente en una tabla de pedidos, habr una relacin de dependencia con el maestro de
clientes, mediante el cdigo de cliente y con el maestro de artculos, mediante el correspondiente cdigo.
Eso por lo menos.
Este tipo de relaciones, normalmente, se establecen para que no pueda haber supresin de artculos o
clientes si hay pedidos relacionados, ni adicin de pedidos sin cdigo de cliente o cdigo de artculo.
Lgicamente, este tipo de dependencias tambin han de controlarse en las tablas que compongan un DataSet,
para evitar que los mismos problemas se puedan producir en la actualizacin de datos en el mismo y surjan,
brutalmente, al ir a replicar los cambios en la base de datos.
Por lo tanto, todo DataSet dispone de la coleccin DataRelationCollection, en la que registrar las
dependencias de clave primaria/secundaria entre las distintas tablas que lo componen, mediante las
correlaciones entre objetos DataColumn de dos DataTable, siempre y cuando el tipo de datos sea coincidente.
Adems de esto, los objetos DataTable disponen de la coleccin ConstraintCollection, accesible mediante
la propiedad DataTable.Constraints, en la que se registran las restricciones entre tablas, para determinar las
acciones a efectuar al agregar o suprimir registros, mediante las acciones asociadas a sus objetos
UniqueConstraint y ForeignKeyConstraint.
Los objetos UniqueConstraint son para garantizar que las claves son nicas, esto es, que no haya duplicados.
Los objetos ForeignKeyConstraint son los encargados de garantizar que registro asociado a un cdigo, existe
en la tabla maestra y que es lo que se ha de hacer con este registro cuando el de la tabla maestra se elimine.
Se deben utilizar los mtodos, Add, Clear o Remove de ConstraintCollection para la operativa con estas
restricciones.
Tambin dispones del mtodo Contains para saber si una determinada restriccin existe, antes de actuar
contra la tabla y provocar una excepcin.

19

ACCESO A BASE DE DATOS CON ADO.NET


6.6 Filtrado de datos DataView.
Como ya te he comentado antes, el DataView tiene mejor rendimiento a la hora de seleccionar registros o
aplicar ordenaciones que los mtodos de DataTable.
Vamos a ver un pequeo ejemplo de cmo se usa esto, aunque, de momento, seguimos en aplicacin de
consola, ya habr tiempo de pasar a formularios Windows, no te preocupes.

Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Transactions
Module Module1
Dim connectionString As String
Public Sub Main()
Aqu definimos la cadena de conexin
connectionString = Data Source=LG-TONY\SQLEXPRESS2008; & _
Initial Catalog=AdventureWorks;Integrated Security=SSPI;
ConVista()
End Sub
Public Sub ConVista()
Creamos el DataSet
Dim Datos As DataSet = New DataSet()
Datos = CargarDatos()
Contamos cuantos registros se ha traido
Dim cuenta As Integer = Datos.Tables(Production.Product).Rows.Count()
Console.WriteLine(Ha leido: & cuenta & _
registros de la base de datos para la tabla Product)
Mostramos la tabla cargada
Mostrar(Datos.Tables(Production.Product), Tabla original)
Creamos dos DataView sobre la tabla de datos
Dim VistaUno As DataView = New DataView(Datos.Tables(Production.Product))
Dim VistaDos As DataView = New DataView(Datos.Tables(Production.Product))
Cambiamos algn dato
Datos.Tables(Production.Product).Rows(0)(Name) = Primer registro
Datos.Tables(Production.Product).Rows(1)(name) = Segundo registro
Mostramos, como antes, los 10 primeros
Mostrar(Datos.Tables(Production.Product), Tabla con modificaciones)
Le decimos a la primera vista que muestre slo los registros modificados

20

ACCESO A BASE DE DATOS CON ADO.NET


VistaUno.RowStateFilter = DataViewRowState.ModifiedOriginal
Mostramos la vista
Mostrar(VistaUno, Vista de slo modificados)
Aadimos un registro a la segunda vista
Dim fila As DataRowView
fila = VistaDos.AddNew()
fila(ProductID) = 12345
fila(Name) = Prueba de nuevo registro
fila(ProductModelID) = 33
En la segunda vista deseamos slo los registros nuevos o modificados
VistaDos.RowStateFilter = DataViewRowState.ModifiedCurrent Or _
DataViewRowState.Added
Mostramos la vista
Mostrar(VistaDos, Vista de aadidos y modificados)
End Sub
Public Function CargarDatos() As DataSet
Creamos el DataSet
Dim Datos As DataSet = New DataSet(Prueba)
Using connection As New SqlConnection(connectionString)
Creamos el DataAdapter
Dim ProductDA As SqlDataAdapter = New SqlDataAdapter()
Le asignamos la tabla de la que deseamos recuperar informacin
ProductDA.TableMappings.Add(Table, Production.Product)
Definimos el SelectCommand que vamos a utilizar
Dim sql1 As String = SELECT ProductID, Name, ProductModelID & _
FROM Production.Product
Dim sql2 As String = WHERE ProductModelID > 0;
Dim sql As String = sql1 & sql2
Dim ProductSC As SqlCommand = New SqlCommand(sql, connection)
ProductSC.CommandType = CommandType.Text
Asignamos el comando recin creado al DataAdapter
ProductDA.SelectCommand = ProductSC
Se abre la conexin
connection.Open()
Console.WriteLine(Establecida la conexin)
Llenamos el DataSet
ProductDA.Fill(Datos)
Cerramos la conexin
connection.Close()
Console.WriteLine(Conexin cerrada)

21

ACCESO A BASE DE DATOS CON ADO.NET


End Using
Return (Datos)
End Function
Public Sub Mostrar(ByVal Tabla As DataTable, ByVal Etiqueta As String)
Dim i As Integer = 0
Console.WriteLine(Ahora mostraremos el contenido de los 10 primeros & _
registros de & Etiqueta)
Console.WriteLine(ProductID & vbTab & Name & vbTab & vbTab & _
vbTab & ProductModelId)
For Each fila As DataRow In Tabla.Rows
If (fila.Field(Of String)(1).Length() > 24) Then
Console.WriteLine(fila.Field(Of Integer)(0).ToString() & vbTab & _
fila.Field(Of String)(1) & vbTab & _
fila.Field(Of Integer)(2).ToString())
Else
Console.WriteLine(fila.Field(Of Integer)(0).ToString() & vbTab & _
fila.Field(Of String)(1) & vbTab & vbTab & _
fila.Field(Of Integer)(2).ToString())
End If
i += 1
If (i >= 10) Then
Exit For
End If
Next
Como siempre, para que puedas leer lo escrito
Console.ReadLine()
End Sub
Public Sub Mostrar(ByVal Vista As DataView, ByVal Etiqueta As String)
Console.WriteLine(Ahora mostraremos el contenido de los 10 primeros & _
registros de & Etiqueta)
Console.WriteLine(ProductID & vbTab & Name & vbTab & vbTab & vbTab & _
ProductModelId)
For i As Integer = 0 To 10
If (Vista(i).Row.Field(Of String)(1).Length() > 24) Then
Console.WriteLine(Vista(i).Row.Field(Of Integer)(0).ToString() & _
vbTab & Vista(i).Row.Field(Of String)(1) & vbTab & _
Vista(i).Row.Field(Of Integer)(2).ToString())
Else
Console.WriteLine(Vista(i).Row.Field(Of Integer)(0).ToString() & _

22

ACCESO A BASE DE DATOS CON ADO.NET


vbTab & Vista(i).Row.Field(Of String)(1) & vbTab & _
vbTab & Vista(i).Row.Field(Of Integer)(2).ToString())
End If
If i >= Vista.Count - 1 Then
Exit For
End If
Next i
Como siempre, para que puedas leer lo escrito
Console.ReadLine()
End Sub
End Module

Creo que no hay mayor complicacin para comprender el cmo funciona un DataView.
Si pulsamos F5 en el cdigo anterior obtendremos lo siguiente:

23

ACCESO A BASE DE DATOS CON ADO.NET

EN RESUMEN
El modo de acceso desconectado a datos est previsto para evitar los bloqueos en las bases de
datos y la saturacin de ancho de banda.
Se caracteriza por la utilizacin de DataAdapters para llenar los DataSets, los cuales estn
compuestos de DataTables, que vienen a ser la imagen de las tablas correspondientes
recuperadas de la base de datos.
Has visto que las tablas se mantienen relacionadas mediante su coleccin ConstraintCollection
y la DataRelationCollection de sus DataSet.

24

Vous aimerez peut-être aussi