Vous êtes sur la page 1sur 39

Universidad Privada Telesup Pg.

1
Taller de
programacin
distribuida
Universidad Privada Telesup Pg. 2
UNIDAD DICTICA:
Taller de Programacin Distribuida
CUARTO CICLO
PREACIO
El taller de programacin distribuida, es naturaleza terico - prctico. El contenido ha sido
elaborado para orientar La programacin multiusuarios utilizando el lenguaje de programacin de
acuerdo al diseo moderno y prctico. Lo cual se aplica en el campo de la empresa donde la
bsqueda de proesionales con dichos conocimiento en esta materia es constante y muy bien
remunerada.
!ropone desarrollar en el estudiante las competencias para comprender el undamento y aplicacin
de las principales t"cnicas en la programacin multiusuarios.
E!TRUCTURA DE LO! CONTENIDO!
CAP"TULO I: DI!E#O DE OR$ULARIO
Crear a%licaciones
$DI& men' ( barras
de )erramientas
Creando A%licaciones
$DI
ormulario Padre&
)i*o
Controles de Acceso+
Usuario& Pass,ord&
Progreso -arras&
-arra de Estado
CAP"TULO II: AR.UITECTURA / PRO0EEDORE! DE DATO!
Dise1o de
a%licaciones con
ar2uitectura
+NET
Ar2uitectura
uncionalidad (
Acceso a base de datos
con ADO+NET
Es%acio de nombres
%ara datos (
Pro3eedor de Datos
+NET rame,or4
Ob*etos %ro3istos %or
distintos %ro3eedores
de datos +NET
CAP"TULO III: ACCE!O A -A!E DE DATO! RE$OTA
Dise1o de base de
datos ADO+NET
A%licaciones con
cone5in remota
Ar2uitectura
ADO+NET Ob*etos (
Clases %rinci%ales
Acceso a Datos
escenarios conectado (
desconectado&
Consultas
Instrucciones
%rinci%ales %ara
reali6ar el
mantenimiento de una
-ase de Datos
CAP"TULO I0: CON!ULTA! CON CONE7I8N A -A!E DE DATO!
Consultas:
A%licacin con
tablas
relacionadas
Clases Data Relatio+
$9todos %ro%iedades
im%lementacin
Em%leo de la cl:usula
Inner ;oin+ De la
instruccin !elect de
!.L
Procedimientos
Almacenados&
Conce%to& Ti%os e
Im%lementacin
CO$PETENCIA DE LA CARRERA PROE!IONAL
#isear, eectuar y negociar el uso de las dierentes tecnolog$as de %normacin y &omunicacin
de una %nstitucin, a partir del anlisis de sus requerimientos, teniendo en cuenta los criterios de
calidad, seguridad y "tica proesional propiciando el trabajo en equipo
CO$PETENCIA <ENERAL DEL CUR!O
#esarrollar sot'are multiusuario utilizando un lenguaje de programacin, de acuerdo al diseo,
utilizando las ms modernas herramientas para la programacin de aplicaciones con cone(in a
base de datos en orma remota.
Universidad Privada Telesup Pg. 3
Presentacin ( conte5tuali6acin+
Los temas que se tratan en la presente )nidad, tienen por inalidad que el estudiante conozca
los conceptos bsicos del #iseo de ormulario en .*E+ ,rame'or-.
Com%etencia
&omprende correctamente la creacin de ormularios, agregando todo tipo de controles
utilizando las t"cnicas .#% en orma terica / prctica.
Ca%acidades
Entiende los conceptos bsicos de los controles en los ormularios
0plica las t"cnicas del diseo .#%
.aneja controles de acceso y elaboracin de dierentes tipo de barras de herramientas.
Actitudes
!articipa en las acti1idades de 2rupo
3espeta la opinin de los dems
Es responsable de los a1ances y producto inal
.uestra %nter"s y 1alora el curso en su ormacin proesional
.uestra disposicin y adaptacin para el trabajo en equipo
%n1estiga por iniciati1a propia
Ideas b:sicas ( contenidos esenciales de la Unidad+
La )nidad de 0prendizaje %4 #iseo de ,ormularios.
&rear aplicaciones .#%, men y barras de herramientas
&reando 0plicaciones .#%
,ormulario !adre, hijo
&ontroles de 0cceso. )suario, !ass'ord,
!rogreso 5arras, 5arra de Estado
ormularios de inter=a6 m'lti%le >$DI?
A%licaciones de estilo !DI
)na aplicacin de tipo o estilo 6#% 76ingle #ocument %nterace8, %nteraz de #ocumento 6encillo, est
compuesta undamentalmente de un nico ormulario, a tra1"s del cual, el usuario realiza toda la
interaccin con el programa. &omo ejemplos de este tipo de aplicacin tenemos el 5loc de *otas o la
&alculadora de 9indo's.
)n programa 6#% puede tener ms de un ormulario, aunque no sea algo habitual. &uando eso ocurre,
los ormularios se ejecutan independientemente, sin un elemento contenedor que los organice.
A%licaciones de estilo $DI
)na aplicacin de tipo o estilo .#% 7.ultiple #ocument %nterace8, %nteraz de #ocumento .ltiple,
se compone de un ormulario principal, tambi"n denominado ormulario .#%, que actuar como
contenedor de otros ormularios 7documentos8 abiertos durante el transcurso del programa,
denominados ormularios hijos o secundarios .#%. &omo ejemplos de este tipo de aplicacin tenemos
!o'er!oint o 0ccess.
0 dierencia de lo que ocurr$a en 1ersiones anteriores de :5, un ormulario .#% admite los mismos
controles que un ormulario normal, aunque dada su orientacin de ormulario contenedor, se
recomienda limitar los controles en un .#% a los estrictamente necesarios. El men es el ejemplo ms
identiicati1o de control idneo para un ormulario .#%, ya que a tra1"s de sus opciones, podremos
abrir los ormularios hijos de la aplicacin.
CAP"TULO I: DI!E#O DE OR$ULARIO
Crear a%licaciones $DI
Universidad Privada Telesup Pg. 4
6eguidamente describiremos el proceso de creacin de un proyecto que contenga un ormulario .#% y
dos ormularios hijos, as$ como el comportamiento de estos ltimos cuando son abiertos dentro del
ormulario padre .#%. Este ejemplo tiene el nombre .#%!ru, y se debe hacer clic aqu$ para acceder
al mismo.
)na 1ez creado el nue1o proyecto, cambiaremos el nombre del ormulario por deecto a rm!rincipal.
!ara conseguir que este ormulario tenga el comportamiento de un contenedor .#%, debemos asignar
el 1alor +rue a su propiedad %s.di&ontainer. +ambi"n debemos establecer a este ormulario como
inicial en las propiedades del proyecto.
0hora pasaremos a la creacin de los ormularios hijos del .#%. El primero, rm&arta, permite la
escritura en un +e(t5o( multil$nea, cuyo contenido podremos grabar a un archi1o en disco. La ,igura
;<= muestra este ormulario.
,igura ;<=. ,ormulario hijo de .#% para escribir un te(to largo.
El cdigo del botn que realiza la grabacin del te(to lo podemos 1er en el &digo uente ><?.
#ebemos importar el espacio de nombres 6ystem.%@, ya que en esta clase del ormulario hacemos uso
de los tipos ,ile y 6tream9riter.
Private Sub btnGrabar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnGrabar.Click
' escribir en un archivo el contenido
' del TextBox
Dim oEscritor As StreamWriter
oEscritor = File.CreateText(Me.txtArchivo.Text)
oEscritor.Write(Me.txtCarta.Text)
oEscritor.Close()
End Sub
&digo uente ><?
El otro ormulario hijo, rm%no, muestra la echa y hora actualA esta ltima es actualizada a tra1"s del
control +imer tmr+iempo. :er la ,igura ;<;.
Universidad Privada Telesup Pg. 5
,igura ;<;. ,ormulario hijo de .#% para mostrar echa y hora actuales.
El &digo uente ><B muestra las instrucciones que se ejecutan en el e1ento +ic- del control +imer.
Private Sub tmrTiempo_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles tmrTiempo.Tick
Dim dtFecha As Date
dtFecha = DateTime.Today
Dim dtHora As Date
dtHora = DateTime.Now
Me.lblFecha.Text = dtFecha.ToString("d/MMM/yyyy")
Me.lblHora.Text = dtHora.ToString("h:m:s")
End Sub
&digo uente ><B
El siguiente paso consiste en crear un men para poder abrir los ormularios hijos a tra1"s de sus
opciones. :er ,igura ;<C.
,igura ;<C. .en del ormulario .#%.
En las opciones &arta e %normacin del men, instanciaremos un objeto del ormulario
correspondiente, teniendo en cuenta que para conseguir que dichos ormularios se comporten como
hijos del .#%, debemos asignar a su propiedad .di!arent, la instancia actual del ormulario en
ejecucin, es decir, .e. :eamos este punto en el &digo uente ><<.
Private Sub mnuCarta_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuCarta.Click
Dim ofrmCarta As New frmCarta()
' con la siguiente lnea conseguimos que el
' formulario se comporte como hijo del actual
ofrmCarta.MdiParent = Me
ofrmCarta.Show()
End Sub
Private Sub mnuInformacion_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuInformacion.Click
Dim ofrmInfo As New frmInfo()
' con la siguiente lnea conseguimos que el
' formulario se comporte como hijo del actual
ofrmInfo.MdiParent = Me
ofrmInfo.Show()
End Sub
&digo uente ><<
En la ,igura ;<> mostramos el ormulario .#% en ejecucin, conteniendo a los ormularios hijos
dependientes.
Universidad Privada Telesup Pg. 6
,igura ;<>. 0plicacin .#% en ejecucin.
Creacin de men's de ti%o 0entana& en =ormularios $DI
Es probable que el lector haya obser1ado, en algunas aplicaciones 9indo's de tipo .#%, que e(iste
en la barra de mens de la 1entana principal, un men con el nombre :entana o 9indo' 7depende del
idioma del programa8, que nos muestra los nombres de los ormularios hijos abiertos, permiti"ndonos
cambiar de ormulario acti1o al seleccionar una de esas opciones.
En nuestras aplicaciones .#% tambi"n podemos disponer de un men de este tipo, aadiendo una
nue1a opcin al men principal del ormulario .#%, y asignando a su propiedad .diList el 1alor
+rue.
0dicionalmente, y para darle un aspecto ms proesional a este men, podemos aadir los .enu%tem
correspondientes a la organizacin de los ormularios hijos en &ascada, .osaico Dorizontal, etc. !ara
organizar los ormularios abiertos en la aplicacin en alguno de estos modos, deberemos ejecutar el
m"todo Layout.di7 8 del ormulario .#%, pasndole como parmetro uno de los 1alores
correspondiente a la enumeracin .diLayout. El &digo uente EFF muestra las opciones
correspondientes a la organizacin en cascada y en mosaico horizontal de nuestro ejemplo.
Private Sub mnuCascada_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuCascada.Click
Me.LayoutMdi(MdiLayout.Cascade)
End Sub
Private Sub mnuHorizontal_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuHorizontal.Click
Me.LayoutMdi(MdiLayout.TileHorizontal)
End Sub
&digo uente EFF
La ,igura ;<E muestra el mencionado men
:entana de este proyecto, en cual contiene
en este caso
los nombres de los ormularios abiertos que
acaban de ser organizados en mosaico
1ertical.
,igura ;<E. .en 1entana en ormulario
.#%.
Universidad Privada Telesup Pg. 7
-lo2ueo de o%ciones de men' en =ormularios $DI
En la aplicacin de ejemplo que estamos desarrollando, podemos abrir tantas copias de los ormularios
hijos como necesitemos.
3especto al ormulario que nos permite escribir un te(to para grabar a un archi1o, es til poder tener
1arios ormularios de este tipo, ya que podemos trabajar con di1ersos archi1os a la 1ez.
#el ormulario hijo que muestra la echa y hora actual sin embargo, tener ms de una copia no parece
algo muy lgico, ya que se trata simplemente de disponer de una inormacin 1isualizada, y repetirla a
tra1"s de la apertura de 1arios ormularios iguales no tiene mucho sentido.
!ara conseguir que de un determinado ormulario hijo slo podamos abrir una instancia, debemos
hacer dos cosas4 en primer lugar, en el manipulador de e1ento correspondiente a la opcin de men
que abre dicho ormulario, asignaremos ,alse a la propiedad +rue de la mencionada opcin de men.
:emoslo en el &digo uente EF=.
Private Sub mnuInformacion_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuInformacion.Click
' deshabilitamos esta opcin de men
Me.mnuInformacion.Enabled = False ' <-----
Dim ofrmInfo As New frmInfo()
' con la siguiente lnea conseguimos que el
' formulario se comporte como hijo del actual
ofrmInfo.MdiParent = Me
ofrmInfo.Show()
End Sub
&digo uente EF=
En segundo lugar, dentro del cdigo del ormulario hijo, en nuestro caso rm%no, debemos escribir el
manipulador para el e1ento &losed del ormulario. Este e1ento se produce cuando se ha cerrado el
ormulario, por lo que desde aqu$ 1ol1eremos a acti1ar la opcin de men del ormulario padre, que
hab$amos deshabilitado.
!ara acceder desde un ormulario hijo a su .#% contenedor, disponemos de la propiedad .di!arent,
que nos de1uel1e una reerencia de dicho ormulario padre. @bser1e el lector en el &digo uente EF;,
cmo adems de utilizar la mencionada propiedad, la potencia de la uncin &+ype7 8 nos permite en
una sola l$nea de cdigo, lle1ar a cabo esta accin.
' al cerrar este formulario, activamos de nuevo
' la opcin de men del formulario padre que
' permite crear instancias de este formulario
Private Sub frmInfo_Closed(ByVal sender As Object, ByVal e As System.EventArgs)
Handles MyBase.Closed
' utilizando la funcin CType(), moldeamos
' la propiedad MdiParent del formulario al tipo
' correspondiente a la clase del formulario MDI;
' con ello obtenemos acceso a sus miembros, y en
' particular a la opcin de men que necesitamos
' habilitar
CType(Me.MdiParent, frmPrincipal).mnuInformacion.Enabled = True
End Sub
&digo uente EF;
La ,igura ;<G muestra el resultado al ejecutar. .ientras que el
ormulario de inormacin est" abierto,
su opcin de men en el .#% estar deshabilitada.
,igura ;<G. @pcin de ormulario hijo deshabilitada.
Universidad Privada Telesup Pg. 8
Recorrer los =ormularios )i*os de un $DI
La clase ,orm tiene la propiedad .di&hildren, que de1uel1e un array con todos los ormularios hijos
abiertos hasta el momento.
Esto nos permite recorrer todo este conjunto de ormularios para realizar operaciones con alguno de
ellos o todos.
El &digo uente EFC muestra un ejemplo de uso de esta propiedad, en el que mostramos el t$tulo de
cada ormulario hijo, y adems, cambiamos su color de ondo.
Dim oFormHijos() As Form
oFormHijos = Me.MdiChildren
Dim oForm As Form
For Each oForm In oFormHijos
MessageBox.Show("Ttulo de ventana: " & oForm.Text)
oForm.BackColor = Color.Beige
Next
&digo uente EFC
Com%ortamiento No $odal >$odeless? de =ormularios
)n ormulario de comportamiento no modal, permite el libre cambio de oco entre el resto de
ormularios de la aplicacin.
)na clara muestra la hemos 1isto en el proyecto de ejemplo realizado durante los ltimos apartados
del te(to. En dicha aplicacin, pod$amos abrir 1arios ormularios hijos dentro del ormulario .#%
principal, y pasar de uno a otro sin restricciones.
@tra caracter$stica de los ormularios no modales reside en que una 1ez creados y 1isualizados, el resto
del cdigo de la aplicacin contina su ejecucin. :er &digo uente EF>.
Dim ofrmCarta As New frmCarta()
' crear formulario hijo de un mdi
ofrmCarta.MdiParent = Me
ofrmCarta.Show()
' despus de mostrar el formulario hijo
' se muestra a continuacin este mensaje
MessageBox.Show("Se acaba de abrir un formulario hijo")
&digo uente EF>
Com%ortamiento $odal de =ormularios
&omo contrapartida al anterior apartado tenemos los ormularios de comportamiento modal, tambi"n
denominados cuadros o 1entanas de dilogo.
)n ormulario modal, al ser 1isualizado, bloquea el paso a otros ormularios de la aplicacin hasta que
no es cerrado 7aceptado o completado8 por el usuario.
&omo ejemplo de estos ormularios se acompaa el proyecto ,orm#ialogos 7hacer clic aqu$ para
acceder al ejemplo8, del que pasamos a describir su proceso de creacin.
Este proyecto contiene un ormulario .#% llamado rm!rincipal, y uno hijo con el nombre rmDijo,
que abrimos mediante una opcin de menA la creacin de este tipo de ormularios se ha descrito en
apartados anteriores.
0 continuacin aadimos un nue1o ormulario al proyecto con el nombre rm#ialogo, que tambi"n
abriremos a tra1"s de la correspondiente opcin de men del ormulario .#%.
!ara que este ormulario tenga un comportamiento modal, debemos mostrarlo ejecutando el m"todo
6ho'#ialog7 8 de la clase ,orm. En el &digo uente EFE tenemos las instrucciones necesarias.
@bser1e tambi"n el lector, cmo hasta que el ormulario de dilogo no es cerrado, no se mostrar el
mensaje que hay a continuacin de la llamada a 6ho'#ialog7 8. 6i adems intentamos pasar al
ormulario hijo, en el caso de que est" abierto, no podremos.
Private Sub mnuDialogo_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuDialogo.Click
' instanciar el formulario que mostraremos como un dilogo
Dim ofrmDialogo As New frmDialogo()
Universidad Privada Telesup Pg. 9
' dar una posicin al formulario
ofrmDialogo.StartPosition = FormStartPosition.CenterParent
' mostrarlo de forma modal, como cuadro de dilogo
ofrmDialogo.ShowDialog()
MessageBox.Show("Se ha cerrado el dilogo")
End Sub
&digo uente EFE
!ara cerrar un ormulario modal podemos, al igual que para cualquier ormulario, ejecutar su m"todo
&lose7 8. *o obstante, un ormulario de dilogo suele proporcionar, aunque esto no es obligatorio, los
t$picos botones para aceptar, cancelar, reintentar, etc.A de modo que una 1ez cerrado el ormulario,
podamos a1eriguar qu" botn puls el usuario.
!odemos proporcionar este comportamiento en nuestros ormularios modales, asignando a la
propiedad #ialog3esult de la clase ,orm, uno de los 1alores del tipo enumerado #ialog3esult. Esto
tendr como eecto adicional el cierre del cuadro de dilogo.
!or lo tanto, 1amos a aadir a nuestro ormulario rm#ialogo, dos controles 5utton4 btn0ceptar y
btn&ancelar, en los que escribiremos las instrucciones del &digo uente EFG.
Private Sub btnAceptar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnAceptar.Click
' asignar un valor a esta propiedad,
' cierra al mismo tiempo el formulario
Me.DialogResult = DialogResult.OK
End Sub
Private Sub btnCancelar_Click(ByVal sender As Object, ByVal e As
System.EventArgs)
Handles btnCancelar.Click
' asignar un valor a esta propiedad,
' cierra al mismo tiempo el formulario
Me.DialogResult = DialogResult.Cancel
End Sub
&digo uente EFG
&omo ayuda en la construccin de ormularios modales de dilogo, la clase ,orm dispone de las
propiedades 0ccept5utton y &ancel5utton, a las que podemos asignar sendos controles 5utton que
sern ejecutados al pulsar las teclas H%*+3@I y HE6&0!EI respecti1amente.
Esto es lo que haremos en el ormulario rm#ialogo, asignando a 0ccept5utton el control btn0ceptar,
y en &ancel5utton asignaremos btn&ancelar.
,inalmente, en el e1ento de la opcin de men que abre este ormulario modal, correspondiente a
rm!rincipal, aadiremos, tras la llamada a 6ho'#ialog7 8, el cdigo que comprobar el resultado de
la ejecucin del ormulario de dilogo. :er el &digo uente EF?.
Private Sub mnuDialogo_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles mnuDialogo.Click
' instanciar el formulario que mostraremos como un dilogo
Dim ofrmDialogo As New frmDialogo()
' dar una posicin al formulario
ofrmDialogo.StartPosition = FormStartPosition.CenterParent
' mostrarlo de forma modal, como cuadro de dilogo
ofrmDialogo.ShowDialog()
' comprobar lo que ha hecho el usuario
' en el cuadro de dilogo
Dim Resultado As DialogResult
Resultado = ofrmDialogo.DialogResult
If Resultado = DialogResult.OK Then
MessageBox.Show("Datos del dilogo: " & _
ofrmDialogo.txtNombre.Text & " " & _
ofrmDialogo.txtApellidos.Text)
Else
MessageBox.Show("Se ha cancelado el dilogo")
End If
Universidad Privada Telesup Pg. 10
End Sub
&digo uente EF?
La ,igura ;<? muestra el programa en ejecucin. &omo puede comprobar el lector, el ormulario
modal, debido a su comportamiento, no se encuentra limitado a los bordes del ormulario .#%A pero
depende de este ltimo, ya que si intentamos pasar el oco a un ormulario hijo, no podremos.
,igura ;<?. ,ormulario modal de dilogo en ejecucin.
0alidacin de controles
Los controles 9indo's 1ienen pro1istos de un potente y le(ible sistema de 1alidacin, que nos
permitir comprobar si el usuario introduce los 1alores adecuados en un control, de modo que le
permitiremos pasar el oco a otro control, u obligarle a permanece en el actual hasta que su 1alor no
sea correcto.
En este esquema de 1alidacin, los miembros principales de la clase &ontrol que inter1ienen son los
siguientes.
Causes0alidation+ Esta propiedad nos permite establecer un 1alor lgico, de manera que
cuando un control capture el oco, pro1ocar la 1alidacin para otro control del ormulario que
la requiera.
0alidating+ Este e1ento se produce para que podamos escribir el cdigo de 1alidacin
oportuno en un manipulador de e1ento. El procedimiento manejador de e1ento recibe entre sus
parmetros un objeto de tipo &ancelE1ent0rgs, por lo que si la 1alidacin no es correcta,
asignaremos ,alse a la propiedad &ancel de dicho objeto.
0alidated+ Este e1ento se produce en el caso de que la 1alidacin haya tenido "(ito.
El proyecto de ejemplo :alidar&ontrol 7hacer clic aqu$ para acceder a este ejemplo8 consta de un
ormulario con tres controles +e(t5o(. +odos tienen el 1alor +rue en su propiedad &auses:alidation,
y adicionalmente, para el control t(t%mporte hemos escrito el procedimiento que actuar como
manipulador del e1ento :alidatingA con ello impediremos el paso desde dicho control a los dems
hasta que su contenido no sea num"rico. 6i pasamos la 1alidacin, se ejecutar en ese caso el cdigo
del e1ento :alidated. :eamos estos manipuladores de e1ento en el &digo uente E;F.
Private Sub txtImporte_Validating(ByVal sender As Object, ByVal e As
System.ComponentModel.CancelEventArgs) Handles txtImporte.Validating
If Not IsNumeric(Me.txtImporte.Text) Then
e.Cancel = True
MessageBox.Show("Se requiere un nmero")
End If
End Sub
&digo uente E;F
Universidad Privada Telesup Pg. 11
La ,igura C=; muestra esta aplicacin en uncionamiento, durante la ejecucin del e1ento de
1alidacin.
En el control t(t,echa por otro lado, podemos teclear cualquier 1alor, aunque no sea echa, ya que no
proporcionamos manipuladores de e1ento para 1alidar su contenido.
&uando escribimos cdigo de 1alidacin empleando estos miembros de la clase &ontrol hemos de
tener presente el comportamiento, a 1eces no muy intuiti1o, del sistema de 1alidacin para controles
en los ormularios 9indo's.
,igura C=;. :alidacin de un control.
&omo hemos mencionado anteriormente, cuando la propiedad &auses:alidation de un control
contiene +rue, al recibir el oco dicho control, se pro1ocar el e1ento de 1alidacin para el control que
acaba de perder el oco. !ero si pasamos el oco a un control en el que &auses:alidation contiene
,alse, la 1alidacin no se producir sobre el control que acaba de perder el oco.
Esto lo podemos comprobar muy cilmente sobre nuestro proyecto de ejemplo, asignando al control
t(t,echa el 1alor ,alse en su &auses:alidation. 0 partir de ahora, cuando estemos situados en el
control t(t%mporte, si este no contiene un nmero, se producir la 1alidacin si pasamos el oco a
t(t*ombre, pero no se 1alidar si pasamos a t(t,echa.
Controles a3an6ados
Los controles del &uadro de herramientas del %#E tratados hasta el momento, son los que podr$amos
considerar bsicos o estndar en todas las aplicacionesA no obstante, esta 1entana de herramientas
dispone de otra serie de controles a1anzados o adicionales, que si bien, no son imprescindibles para
conseguir la uncionalidad elemental del programa, sir1en como un magn$ico complemento a la hora
de dotar a nuestras aplicaciones de un interaz de usuario plenamente operati1o.
En los siguientes apartados desarrollaremos un proyecto con el nombre &ontrol01anzado 7hacer clic
aqu$ para acceder a este ejemplo8, a tra1"s del cual, realizaremos una descripcin general de algunos
de estos controles adicionales y su modo de uso.
&omo primer paso en este proyecto, eliminaremos el ormulario por deecto, aadiendo a continuacin
uno nue1o con el nombre rm!rincipal, al que daremos la caracter$stica .#% mediante la propiedad
%s.di&ontainer. En este ormulario crearemos un men con un conjunto de opciones generales4 0brir,
2uardar, 6alir, etc.
-arra de estado >!tatus-ar?
!ara mostrar una barra inormati1a de estado recurriremos a este control, que al dibujarse queda
situado en la parte inerior del ormularioA como nombre le daremos sbrEstado. #e orma similar al
+ool5ar, un control 6tatus5ar est compuesto de una coleccin de objetos !anel, que iremos
aadiendo al control mediante la propiedad !anels, la cual mostrar una 1entana para la creacin y
coniguracin de tales paneles. :er ,igura C=G.
Universidad Privada Telesup Pg. 12
,igura C=G. Editor de paneles del control 6tatus5ar.
Entre las propiedades destacables de un objeto !anel podemos mencionar las siguientes.
-order!t(le. .uestra el panel con eecto resaltado, hundido o normal.
Icon. !ermite asociar un icono al panel.
Auto!i6e. &on esta propiedad podemos conseguir que el panel se redimensione ajustndose a
su contenido o que tenga un tamao ijo.
En este ejemplo, hemos aadido dos paneles a la barra de estado del ormulario. En uno mostramos un
te(to ijoA mientras que en el otro, 1isualizamos la hora actual a tra1"s de un objeto +imer que
ponemos en marcha en el e1ento Load del ormulario. :eamos los m"todos implicados, en el &digo
uente E;>.
Private Sub frmPrincipal_Load(ByVal sender As Object, ByVal e As
System.EventArgs)
Handles MyBase.Load
' al cargar el formulario, creamos un temporizador
' le asociamos un manejador para su evento Tick
' y lo iniciamos
Dim oTiempo As New Timer()
oTiempo.Interval = 1000
AddHandler oTiempo.Tick, AddressOf PonerHoraActual
oTiempo.Start()
End Sub
Private Sub PonerHoraActual(ByVal sender As Object, ByVal e As EventArgs)
' actualizamos a cada segundo la hora de un panel
' de la barra de estado
Me.sbrEstado.Panels(1).Text = DateTime.Now.ToString("HH:mm:ss")
End Sub
&digo uente E;>
La ,igura C=? muestra el ormulario con la barra de
estado.
,igura C=?. ,ormulario con 6tatus5ar.
Universidad Privada Telesup Pg. 13
Presentacin ( conte5tuali6acin+
Los temas que se tratan en la presente )nidad, tienen por inalidad que el estudiante pueda
desarrollar aplicaciones con arquitectura 0#@.*E+ en orma prctica y proesional.
Com%etencia
#esarrollar las habilidades y t"cnicas necesarias para poder disear aplicaciones 0#@.*E+ y
a la 1ez utilizar los dierentes objetos de dierentes pro1eedores.
Ca%acidades
#isea aplicaciones con arquitectura .*E+.
!uede realizar cone(iones a base de datos.
)tiliza los dierentes objetos de pro1eedores distintos
.aneja las dierentes t"cnicas para el acceso a base de datos.
Actitudes
!articipa en las acti1idades de 2rupo
3espeta la opinin de los dems
Es responsable de los a1ances y producto inal
.uestra %nter"s y 1alora el curso en su ormacin proesional
.uestra disposicin y adaptacin para el trabajo en equipo
%n1estiga por iniciati1a propia
Ideas b:sicas ( contenidos esenciales de la Unidad+
La )nidad de 0prendizaje %4 0rquitectura y !ro1eedores de #atos
Lenguaje de modelado ).L #iseo de aplicaciones con arquitectura .*E+
0rquitectura ,uncionalidad y 0cceso a base de datos con 0#@.*E+
Espacio de nombres para datos y
!ro1eedor de #atos .*E+ ,rame'or-
@bjetos pro1istos por distintos pro1eedores de datos .*E+
Integrando lo 3isto )asta el momento
Los ejemplos de los temas anteriores constituyen un buen comienzo, y nos han permitido dar nuestros
primeros pasos tanto con el lenguaje como con el %#E, pero e1identemente, no nos 1an a lle1ar muy
lejos si lo que pretendemos es crear aplicaciones con algo ms de contenido.
En este tema no 1amos a entrar toda1$a en los detalles del %#E ni en el lenguaje. !ara que el lector siga
amiliarizndose con el entorno, daremos unos pequeos pasos iniciales msA con ello pretendemos
que se adquiera una mejor 1isin global tanto del lenguaje :5.*E+ como de su herramienta de
trabajo4 :isual 6tudio .*E+.
Un %rograma m:s o%erati3o
En este tema 1amos a escribir una aplicacin algo ms completa, que consistir en un ormulario en el
que introduciremos el nombre de un ichero y un pequeo te(to, que seguidamente grabaremos en
nuestro equipo. 0s$ que, una 1ez esbozado el objeti1o a conseguir... manos a la obra.
Dise1o del =ormulario
#espu"s de iniciar :6.*E+, crearemos un nue1o proyecto al que daremos el nombre de Escritor+e(to
7para acceder a Escritor+e(to, el proyecto de este ejemplo, hacer clic aqu$8. En el ormulario del
proyecto, ,orm=, aadiremos los controles que permitirn al usuario escribir un te(to, grabar dicho
te(to en un ichero, etc. En concreto aadiremos dos controles Label, dos +e(t5o( y dos 5utton, cuya
ubicacin en la 1entana del &uadro de herramientas mostramos en la ,igura G=
CAP"TULO II: AR.UITECTURA / PRO0EEDORE! DE DATO!
#iseo de aplicaciones con arquitectura .*E+
Universidad Privada Telesup Pg. 14
.
,igura G=. &ontroles que debemos dibujar en el ormulario del ejemplo.
La orma de dibujar un control en un ormulario ya ha sido e(plicada anteriormente, por lo que
directamente mostramos en la ,igura G;, el ormulario resultante con los controles ya insertados, en
donde indicamos el tipo de control y el nombre que hemos asignado a cada control en su propiedad
*ame.
,igura G;. ,ormulario para la grabacin de un te(to en un ichero.
0 continuacin detallamos bre1emente la uncionalidad de cada uno de los controles de este
ormulario4
Label@& LabelA. .uestran un simple literal que indica al usuario lo que debe introducir en los
controles de te(to.
t5tNombreic)ero. &ontiene el nombre que daremos al ichero en el que grabaremos el te(to.
t5tTe5to. &ontiene el te(to que se 1a a guardar en un ichero. La dierencia de este control,
con el otro control de tipo +e(t5o( del ormulario, reside en que permite escribir 1arias l$neas
de te(to, gracias a que hemos asignado a su propiedad .ultiline el 1alor +rue. La propiedad
.ultiline por deecto contiene ,alse, lo que indica que un +e(t5o( slo permite introducir el
te(to en una nica l$nea.
btn<rabar. 0l pulsar este botn, se tomar el te(to del control t(t+e(to y se grabar en un
ichero con el nombre que contenga el control t(t*ombre,ichero. :eremos como escribir el
cdigo para un control ms adelante.
Universidad Privada Telesup Pg. 15
btn!alir. 0l pulsar este botn, se inalizar la ejecucin del programa, de igual orma que si
pulsramos el botn de cierre del ormulario o H0L+J,>I.
@bser1e el lector que al asignar el nombre de algunos controles, hemos utilizado un preijo. 0s$, para
un +e(t5o( utilizamos el preijo t(t 7t(t*ombre&ontrol8A para un 5utton, btn 7btn*ombre&ontrol8,
etc.
Esta t"cnica, denominada convenciones de notacin, consiste en una serie de normas no obligatorias,
utilizadas a la hora de escribir el cdigo, y que son pactadas generalmente en equipos de trabajo, de
manera que cuando un programador debe tomar parte de un proyecto que ha estado desarrollando otro
programador, la interpretacin del cdigo se acilita, y el desarrollo del proyecto en este sentido, se
dinamiza.
El programador independiente puede igualmente utilizar este tipo de con1enciones, ya que gran parte
del cdigo uente que circula en art$culos, demos, aplicaciones share'are, etc., emplean una serie de
con1enciones gen"ricas de notacin, por lo que si necesita en algn momento compartir su cdigo, la
legibilidad del mismo se acilita.
La +abla > muestra una serie de con1enciones para la codiicacin de los nombres de controles, que
proponemos como ejemplo, para que el lector utilice estas o alguna similar.
Control Pre=i*o
+abla >. &on1enciones de notacin para controles de ormulario.
!ara el ormulario podemos utilizar el preijo rm.
Acceso a datos con ADO +NET
En los siguientes temas 1amos a tratar el acceso a datos desde :5.*E+, haciendo uso del nue1o
modelo de acceso a datos incluido en la plataorma .*E+ ,rame'or-4 0#@ .*E+.
.ostraremos las tareas bsicas para el acceso a datos desde aplicaciones basadas en ormularios
9indo's, empleando la tecnolog$a proporcionada por 0#@ .*E+.
0#@ .*E+ es la nue1a 1ersin del modelo de objetos 0#@ 70cti1eK #ata @bjects8, es decir, la
estrategia que orece .icrosot para el acceso a datos. 0#@ .*E+ ha sido ampliado para cubrir todas
Universidad Privada Telesup Pg. 16
las necesidades que 0#@ no orec$a, y est diseado para trabajar con conjuntos de datos
desconectados, lo que permite reducir el trico de red. 0#@ .*E+ utiliza K.L como ormato
uni1ersal de transmisin de los datos.
0#@ .*E+ posee una serie de objetos que son los mismos que aparecen en la 1ersin anterior de
0#@, como pueden ser el objeto &onnection o &ommand, e introduce nue1os objetos tales como el
objeto #ata3eader, #ata6et o #ata:ie'.
0#@ .*E+ se puede deinir como4
)n conjunto de interaces, clases, estructuras y enumeraciones que permiten el acceso a datos
desde la plataorma .*E+ de .icrosot
La e1olucin lgica del 0!% 0#@ tradicional de .icrosot
!ermite un modo de acceso desconectado a los datos, los cuales pueden pro1enir de mltiples
uentes de datos, de dierente arquitectura de almacenamiento
6oporta un completo modelo de programacin y adaptacin, basado en el estndar K.L
6eguidamente 1amos a realizar una descripcin gen"rica de la arquitectura de 0#@ .*E+, y ms tarde
1eremos como utilizarlo desde aplicaciones :5.*E+
Ar2uitectura de datos desconectados
0#@ .*E+ est basado en una arquitectura desconectada de los datos. En una aplicacin de datos se
ha comprobado que mantener los recursos reser1ados mucho tiempo, implica reducir el nmero de
usuarios conectados y aumenta el proceso del sistema al mantener una pol$tica de bloqueos y
transacciones. 0l mismo tiempo, si la aplicacin mantiene ms de un objeto simultneamente, se
encuentra con el problema de tener que estar continuamente conectando con el ser1idor para alimentar
las relaciones e(istentes entre ambas, subiendo y bajando inormacin 1$a 3!&.
&on 0#@ .*E+ se consigue estar conectado al ser1idor slo lo estrictamente necesario para realizar la
operacin de carga de los datos en el #ata6et. #e esta manera se reducen los bloqueos y las
cone(iones a la m$nima e(presin. 6e pueden soportar muchos ms usuarios por unidad de tiempo y
disminuyen los tiempos de respuesta, a la par que se aceleran las ejecuciones de los programas.
+radicionalmente, el recoger inormacin de una base de datos ha ido destinado a realizar un proceso
con dicha inormacin4 mostrarla por pantalla, procesarla o en1iarla a algn componente.
,recuentemente, la aplicacin no necesita una nica ila, sino un buen conjunto de ellas. 0dems,
tambi"n recuentemente, ese conjunto de ilas procede no de una tabla sino de una unin de mltiples
tablas 7join de tablas8. )na 1ez que estos datos son cargados, la aplicacin los trata como un bloque
compacto. En un modelo desconectado, es in1iable el tener que conectar con la base de datos cada 1ez
que a1anzamos un registro para recoger la inormacin asociada a ese registro 7condiciones del join8.
!ara solucionarlo, lo que se realiza es almacenar temporalmente toda la inormacin necesaria donde
sea necesario y trabajar con ella. Esto es lo que representa un #ata6et en el modelo 0#@ .*E+.
)n #ata6et es una cach" de registros recuperados de una base de datos que acta como un sistema de
almacenamiento 1irtual, y que contiene una o ms tablas basadas en las tablas reales de la base de
datos. 0dicionalmente, almacena las relaciones y reglas de integridad e(istentes entre ellas para
garantizar la estabilidad e integridad de la inormacin de la base de datos. .uy importante es
recalcar, que los #ata6ets son almacenes pasi1os de datos, esto es, no se 1en alterados ante cambios
subyacentes de la base de datos. Es necesario recargarlos siempre que queramos estar al da, en cuanto
a datos se reiere.
)na de las mayores 1entajas de esta implementacin, es que una 1ez obtenido el #ata6et, "ste puede
ser en1iado 7en orma de lujo K.L8 entre distintos componentes de la capa de negocio, como si de
una 1ariable ms se tratase, ahorrando as$ comunicaciones a tra1"s de la base de datos.
)na consecuencia lgica de este tipo de arquitecturas, es la de conseguir que los #ata6ets sean
independientes de los or$genes de datos. Los dri1ers @LE-#5 transormarn la consulta 6LL en un
cursor representado con una estructura K.L, que es independiente del motor de la base de datos.
Esto nos permitir trabajar con mltiples or$genes de datos, de distintos abricante e incluso en
ormatos que no pertenezcan a bases de datos, por ejemplo, icheros planos u hojas de clculo, lo que
representa un importante punto de compatibilidad y le(ibilidad.
6i a esto unimos el hecho de que disponemos de un modelo consistente de objetos 7(ml#@.8 que es
independiente del origen de datos, las operaciones de los #ata6ets no se 1ern aectadas por dicho
origen.
La persistencia es un concepto muy interesante en el mundo del desarrollo. Es un mecanismo por el
cual un componente puede almacenar su estado 71alores de 1ariables, propiedades, datos...en un
momento concreto del tiempo8 en un soporte de almacenamiento ijo. #e manera, que cuando es
necesario, se puede recargar el componente tal y como qued en una operacin anterior.
Universidad Privada Telesup Pg. 17
En un sistema de trabajo @-Line como el que plantea 0#@ .*E+, la persistencia es un mecanismo
undamental. !odemos cerrar la aplicacin y mantener persistentes todos los #ata6ets necesarios, de
manera que al reiniciarla, nos encontramos los #ata6ets tal y como los dejamos. 0horrando el tiempo
que hubiera sido necesario para recuperar de nue1o toda esa inormacin del ser1idor. @ptimizando
toda1$a ms el rendimiento del sistema distribuido.
Grupo EIDOS 36. Acceso a datos con ADO .NET
El ormato que emplea 0#@ .*E+ para almacenar su estado es K.L. !uesto que ya es un estndar de
la industria, esta persistencia nos orece las siguientes cualidades4
La inormacin puede estar accesible para cualquier componente del sistema que entienda
K.L.
Es un ormato de te(to plano, no binario, que lo hace compatible con cualquier componente de
cualquier plataorma, y recuperable en cualquier circunstancia.
Data!et
El 0!% de 0#@ .*E+ proporciona una superclase, #ata6et, que encapsula lo que ser$a la base de datos
a un ni1el lgico4 tablas, 1istas, relaciones, integridad entre todos ellos, etc., pero siempre con
independencia del tipo de abricante que la dise. 0qu$ se tiene el mejor concepto de datos
desconectados4 una copia en el cliente de la arquitectura de la base de datos, basada en un esquema
K.L que la independiza del abricante, proporcionando al desarrollador la libertad de trabajo
independiente de la plataorma. La ,igura CC< muestra una representacin de este tipo de objeto.
,igura CC<. Esquema de un #ata6et.
Esta clase se compone a su 1ez, de clases de soporte, que representan cada una, los elementos
arquitecturales de la base de datos4 tablas, columnas, ilas, sus reglas de chequeo, sus relaciones, las
1istas asociadas a la tabla, etc.
Es%acios de nombres ( clases en ADO +NET
En el presente apartado 1amos a enumerar bre1emente los principales elementos que orman parte del
0!% de 0#@ .*E+.
!rimero 1amos a comentar los distintos espacios de nombres que constituyen la tecnolog$a 0#@
.*E+4
!(stem+Data. &lases gen"ricas de datos de 0#@ .*E+. %ntegra la gran mayor$a de clases que
habilitan el acceso a los datos de la arquitectura .*E+.
!(stem+Data+!2lClient. &lases del pro1eedor de datos de 6LL 6er1er. !ermite el acceso a
pro1eedores 6LL 6er1er en su 1ersin ?.F y superior.
!(stem+Data+OleDb. &lases del pro1eedor de datos de @le#5. !ermite el acceso a
pro1eedores .*E+ que trabajan directamente contra controladores basados en los 0cti1eK de
.icrosot.
!(stem+Data+!2lT(%es. #einicin de los tipos de datos de 6LL 6er1er. !roporciona la
encapsulacin en clases de todos los tipos de datos nati1os de 6LL 6er1er y sus unciones de
manejo de errores, ajuste y con1ersin de tipos, etc.
!(stem+Data+Common. &lases base, reutilizables de 0#@ .*E+. !roporciona la coleccin
de clases necesarias para acceder a una uente de datos 7como por ejemplo una 5ase de
#atos8.
!(stem+Data+Internal. %ntegra el conjunto de clases internas de las que se componen los
pro1eedores de datos.
#entro del espacio de nombres 6ystem.#ata encontramos las siguientes clases compartidas, que
constituyen el eje central de 0#@ .*E+.
Data!et. 0lmac"n de datos por e(celencia en 0#@ .*E+. 3epresenta una base de datos
desconectada del pro1eedor de datos. 0lmacena tablas y sus relaciones.
Universidad Privada Telesup Pg. 18
DataTable. )n contenedor de datos. Estructurado como un conjunto de ilas 7#ata3o'8 y
columnas 7#ata&olumn8.
DataRo,. 3egistro que almacena n 1alores. 3epresentacin en 0#@ .*E+ de una ilaMtupla
de una tabla de la base de datos.
DataColumn. &ontiene la deinicin de una columna. .etadatos y datos asociados a su
dominio.
DataRelation. Enlace entre dos o ms columnas iguales de dos o mas tablas.
Constraint. 3eglas de 1alidacin de las columnas de una tabla.
DataColumn$a%%ing. :$nculo lgico e(istente entre una columna de un objeto del #ata6et
y la columna $sica de la tabla de la base de datos.
DataTable$a%%ing. :$nculo lgico e(istente entre una tabla del #ata6et y la tabla $sica de
la base de datos.
0dems de estas clases, e(iste otro grupo de clases consistente en las clases espec$icas de un
pro1eedor de datos. Estas clases conorman los aspectos particulares de un abricante de pro1eedores
de datos .*E+. +ienen una sinta(is con el ormato KKK&lase, donde NKKKO es un preijo que
determina el tipo de plataorma de cone(in a datos. 6e deinen en dos espacios de nombre4
6ystem.#ata.6ql&lient y 6ystem.#ata.@le#b.
En la +abla C; se orece una descripcin de las clases que podemos encontrar en estos espacios de
2estin de las transacciones a realizar en la base de datos.
+abla C;
!ara aquellos conocedores de 0#@ en alguna de sus 1ersiones anteriores, podemos hacer una analog$a
o comparacin entre las antiguas clases de 0#@ y las nue1as de 0#@ .*E+. En la ,igura C>= se
puede 1er esta apro(imacin.
Universidad Privada Telesup Pg. 19
,igura C>=. &omparati1a entre las clases de 0#@ y 0#@ .*E+.
Dasta aqu$ hemos realizado una introduccin a la tecnolog$a 0#@ .*E+, repasando su arquitectura y
comentando las clases principales. En lo que resta de tema 1amos a utilizar las distintas clases que nos
orece 0#@ .*E+ desde :5.*E+, para realizar tareas comunes de acceso a datos, como pueden ser
establecer una cone(in, obtener un conjunto de registros, realizar operaciones con los datos, etc.
Universidad Privada Telesup Pg. 20
Presentacin ( conte5tuali6acin+
Los temas que se tratan en la presente )nidad, tienen por inalidad que el estudiante
comprenda como se elabora los diseos de base de datos en aplicaciones con cone(iones
remota utilizando consultas y mantenimiento.
Com%etencia
#esarrollar las t"cnicas, habilidades para la elaboracin de aplicaciones de manejo e base
datos realizando consultas y mantenimiento de datos.
Ca%acidades
#isear base de datos para 0#@.*E+.
)tilizar las &lases y objeto en orma dinmica proesional.
Establecer escenarios conectados y desconectados.
3ealizar consultas de datos.
3ealizar mantenimiento de base de datos
Actitudes
!articipa en las acti1idades de 2rupo
3espeta la opinin de los dems
Es responsable de los a1ances y producto inal
.uestra %nter"s y 1alora el curso en su ormacin proesional
.uestra disposicin y adaptacin para el trabajo en equipo
%n1estiga por iniciati1a propia
Ideas b:sicas ( contenidos esenciales de la Unidad+
La )nidad de 0prendizaje %%%4 0cceso a 5ase de #atos 3emota.
#iseo de base de datos 0#@.*E+
0plicaciones con cone(in remota
0rquitectura 0#@.*E+ @bjetos y &lases principales
0cceso a #atos escenarios conectado y desconectado, &onsultas
%nstrucciones principales para realizar el mantenimiento de una 5ase de #atos
-ene=icios de ADO +NET
0#@ .*E+ orece una buena cantidad de mejoras respecto a modelos anteriores de 0#@. Los
beneicios los podemos agrupar en las categor$as descritas a continuacin.
Intero%erabilidad
Las aplicaciones basadas en 0#@ .*E+ obtienen 1entaja de la le(ibilidad y la masi1a aceptacin del
estndar K.L para el intercambio de datos. !uesto que K.L es el estndar de en1$o de inormacin
entre capas, cualquier componente capaz de %nterpretar los datos K.L puede acceder a la inormacin
de 0#@ .*E+, se encuentre donde se encuentre, y procesarla. 0dems, puesto que la inormacin se
en1$a en lujos de K.L, no importa la implementacin empleada para en1iar o recoger la inormacin
/as$ como la plataorma empleada-. 6implemente se e(ige a los componentes que reconozcan el
ormato K.L empleado para el proceso, en1$o y recepcin de un #ata6et.
$antenimiento
En el ciclo de 1ida de una aplicacin los cambios poco sustanciales y modestos son permisibles. !ero
cuando es necesario abordar un cambio estructural o arquitectnico del sistema, la tarea se 1uel1e
demasiado compleja y a 1eces in1iable. Esto es una gran des1entaja de los sistemas actuales, pues
muchas 1eces se trata de una cuestin de actualizacin de los procesos de la propia empresa. 0dems,
cuanto ms se aumenta el proceso de la operati1a de la empresa, las necesidades de proceso crecen
CAP"TULO III: ACCE!O A -A!E DE DATO! RE$OTA
#iseo de base de datos 0#@.*E+
Universidad Privada Telesup Pg. 21
hasta desbordar las mquinas. Es por ello que se separa la estructura de un programa en 1arias capas.
)na de esas capas es la de datos, que es undamental desarrollar correctamente. 2racias a los
#ata6ets, la tarea de portar y aumentar los procesos de datos y de negocio ser mas sencillo4 el
intercambio de inormacin a tra1"s de K.L, hace que sea ms sencilla la tarea de estructurar en ms
capas la aplicacin, con1irti"ndola en ms modular y cil de mantener.
Programacin
Los programadores pueden acceder a un 0!% de programacin estructurado, de uerte tipiicado y que
adems se concentra en la correcta orma de presentar los datos. &entra en la estructura del lenguaje lo
que un programador necesita para disear los programas sin dar muchos rodeos. El &digo uente EE?
muestra un ejemplo de cdigo sin tipiicar4
....
If CosteTotal > Table("Cliente")("Luis").Column("CreditoDisponible") Then
....
&digo uente EE?
&omo se puede obser1ar, aparecen nombres de objetos gen"ricos del sistema que complican la lectura
del cdigo, a la par que los operadores complican tambi"n la 1isin de la secuencia de acceso a los
datos. !odr$amos interpretar lo que hace gracias a que aparecen los nombres propios de los datos que
necesitamos. El &digo uente EEB muestra un ejemplo un poco ms tipiicado4
....
If CosteTotal > DataSet1.Cliente("Luis").CreditoDisponible Then
....
&digo uente EEB
El ejemplo es e(actamente igual al anterior, pero en este caso, el cdigo se centra ms en los objetos
reales que en el objeto del lenguaje en s$4 las palabras Tale y !olu"n ya no aparecen. En su lugar
1emos que aparecen los nombres de los objetos empleados de la 1ida real, lo que hace el cdigo ms
legible. 6i a esto unimos que los entornos ya son capaces de ayudarnos a escribir el cdigo, toda1$a lo
tenemos ms sencillo, ya que podemos 1er con nuestras palabras el modelo de objetos de datos que
necesitamos en cada momento. %ncluso a ni1el de ejecucin nos 1emos respaldado por un sistema de
control de tipos y errores que nos permitirn proporcionar una robustez innata, que antes no se ten$a
sin pasar por el uso de unciones e(ternas.
Rendimiento
!uesto que trabajamos con objetos de datos desconectados, todo el proceso se acelera, ya que no
tenemos que estar comunicndonos por .arshalling con el ser1idor. 0dems, gracias al modelo de
K.L la con1ersin de tipos no es necesaria a ni1el de &@.. 6e reduce pues el ancho de banda
disponible, se independiza ms el cliente del ser1idor, y se descarga ms a "ste, que puede estar
dedicado a otras tareas en lo que el cliente analiza sus datos.
Escalabilidad
Las aplicaciones 9eb tienen un nmero ilimitado de cone(iones potenciales debido a la
naturaleza de %nternet. Los ser1idores son capaces de atender muy bien decenas y decenas de
cone(iones. !ero cuando hablamos de miles y millones, los ser1idores ya no son capaces de
realizar correctamente su trabajo. Esto es debido a que por cada usuario se mantiene una
memoria de proceso y cone(in, un conjunto de bloqueos de recursos como puedan ser tablas,
$ndices, etc., y una comprobacin de sus permisosA todo ello consume tiempo y recursos.
0#@ .*E+ a1orece la escalabilidad, puesto que su modelo de cone(in @-Line e1ita que
se mantengan los recursos reser1ados ms tiempo del considerado necesario. Esto permite que
ms usuarios por unidad de tiempo puedan acceder a la aplicacin sin problemas de tiempos.
0dems se pueden montar ser1icios en &luster de alta disponibilidad que sern balanceados
automticamente por el sistema sin aectar a las cone(iones 0#@. Lo cual garantiza la
ampliacin del ser1icio sin representar un cambio de arquitectura de diseo.
Las clases Connection
En los ejemplos con datos que 1amos a realizar, se ha utilizado 6LL 6er1er ;FFF como ser1idor de
datos, y undamentalmente, la base de datos *orth'ind.
El primer paso obligado en un acceso a datos consiste en establecer una cone(in con un almac"n de
datos. Esto lo 1amos a conseguir gracias a las clases &onnection de 0#@ .*E+, que nos permitirn
Universidad Privada Telesup Pg. 22
conectarnos a un origen de datos 7ya sea una base de datos o no8 , al igual que en 0#@ clsico
emplebamos el objeto &onnection.
En 0#@ se pod$a ejecutar directamente una sentencia contra el almac"n de datos, o bien abrir un
conjunto de registros 73ecordset8, pero en 0#@ .*E+ no 1amos a realizar esta operacin con este tipo
de objetos.
#ebemos recordar que e(isten dos implementaciones para algunos de los objetos de 0#@ .*E+, cada
uno espec$ico del origen de datos con el que nos 1amos a conectar. Esto ocurre con el objeto
&onnection, que tiene dos 1ersiones, una como pro1eedor de datos de 6LL 6er1er, a tra1"s de la clase
6ystem.#ata.6ql&lient.6ql&onnection, y otra como pro1eedor de datos @LE#5, a tra1"s de la clase
6ysem.#ata.@le#b.@le#b&onnection.
!or norma general, del objeto &onnection utilizaremos los m"todos @pen7 8 y &lose7 8, para abrir y
cerrar cone(iones respecti1amente, con el almac"n de datos adecuado. 0unque tenemos el recolector
de basura que gestiona de orma automtica los recursos y objetos que no son utilizados, es
recomendable cerrar las cone(iones de orma e(pl$cita utilizando el m"todo &lose7 8.
Las cone(iones se abrirn de orma e(pl$cita utilizando el m"todo @pen78, pero tambi"n se puede
hacer de orma impl$cita utilizando un objeto #ata0dapter, esta posibilidad la 1eremos ms adelante.
&uando ejecutamos el m"todo @pen78 sobre un objeto &onnection 76ql&onnection o
@le#b&onnection8, se abrir la cone(in que se ha indicado en su propiedad &onnection6tring, es
decir, esta propiedad indicar la cadena de cone(in que se 1a a utilizar para establecer la cone(in
con el almac"n de datos correspondiente. El m"todo @pen78 no posee parmetros.
El constructor de la clase &onnection 7al decir clase &onnection de orma gen"rica nos estamos
reiriendo en conjunto a las clases 6ql&onnection y @le#b&onnection de 0#@ .*E+8 se encuentra
sobrecargado, y en una de sus 1ersiones recibe como parmetro una cadena que ser la cadena de
cone(in que se aplique a su propiedad &onnection6tring.
6i hacemos uso de la clase 6ql&onnection, en la cadena de cone(in no podremos especiicar una
#6* de @#5&, ya que la cone(in se 1a a realizar en este caso directamente con 6LL 6er1er. P si
utilizamos la clase @le#b&onnection debemos especiicar el pro1eedor @LE#5 que se 1a a utilizar
para establecer la cone(in, una e(cepcin es el pro1eedor @LE#5 para @#5& 7.6#06LL8, que no
puede ser utilizado, ya que el pro1eedor @LE#5 de .*E+ no soporta el pro1eedor de @#5&, en este
caso deberemos realizar la cone(in utilizando el pro1eedor adecuado al almac"n de datos. Los
pro1eedores @LE#5 que son compatibles con 0#@ .*E+ son4
6LL@LE#54 .icrosot @LE #5 !ro1ider or 6LL 6er1er.
.6#0@304 .icrosot @LE #5 !ro1ider or @racle.
.icrosot.Qet.@LE#5.>.F4 @LE #5 !ro1ider or .icrosot Qet.
La sinta(is utilizada para indicar la cadena de cone(in, con las particularidades propias de cada
pro1eedor, 1eremos que es muy similar a la utilizada en 0#@ clsico. El &digo uente EE< muestra
un ejemplo de cone(in con un ser1idor 6LL 6er1er ;FFF, y su posterior descone(in, utilizando un
objeto 6ql&onnection. #ebemos importar el espacio de nombres #ata.6ql&lient para poder utilizar el
objeto. Este cdigo lo podemos asociar a la pulsacin de un botn en un ormulario.
Imports System.Data.SqlClient
'....
Try
' crear el objeto de conexin
Dim oConexion As New SqlConnection()
' pasar la cadena de conexin
oConexion.ConnectionString = "server=(local);" & _
"database=Xnorthwind;uid=sa;pwd=;"
' abrir conexin
oConexion.Open()
MessageBox.Show("Conectado")
' cerrar conexin
oConexion.Close()
MessageBox.Show("Desconectado")
Catch oExcep As SqlException
' si se produce algn error,
' lo capturamos mediante el objeto
' de excepciones particular para
' el proveedor de SQL Server
MessageBox.Show("Error al conectar con datos" & _
ControlChars.CrLf & _
Universidad Privada Telesup Pg. 23
oExcep.Message & ControlChars.CrLf & _
oExcep.Server)
End Try
&digo uente EE<
El &digo uente EGF muestra la misma operacin pero usando el objeto de cone(in para el
pro1eedor de @LE#5. @bser1e el lector las dierencias en las cadenas de cone(in y el objeto de
e(cepcin con respecto al anterior ejemplo, as$ como el espacio de nombres a importar.
Imports System.Data.OleDb
'....
Try
' crear el objeto de conexin
Dim oConexion As New OleDbConnection()
oConexion.ConnectionString = "Provider=SQLOLEDB;" & _
"Server=(local);Database=Northwind;uid=sa;pwd=;"
' abrir conexin
oConexion.Open()
MessageBox.Show("Conectado")
' cerrar conexin
oConexion.Close()
MessageBox.Show("Desconectado")
Catch oExcep As OleDbException
' si se produce algn error,
' lo capturamos mediante el objeto
' de excepciones particular para
' el proveedor de OLEDB
MessageBox.Show("Error al conectar con datos" & _
ControlChars.CrLf & _
oExcep.Message & ControlChars.CrLf & _
oExcep.Source())
End Try
&digo uente EGF
Las clases Command
Establecida una cone(in con un almac"n de datos, la siguiente operacin lgica consiste en en1iarle
sentencias para realizar los distintos tipos de operaciones que habitualmente realizamos con los datos.
Las clases &ommand de 0#@ .*E+ sern las usaremos para realizar tales operaciones.
6ql&ommand y @le#b&ommand, son muy similares al objeto &ommand e(istente en 0#@. El objeto
&ommand nos 1a a permitir ejecutar una sentencia 6LL o un procedimiento almacenado sobre la
uente de datos a la que estamos accediendo.
0 tra1"s de un objeto &ommand tambi"n podremos obtener un conjunto de resultados del almac"n de
datos. En este caso, los resultados se pasarn a otros objetos de 0#@ .*E+, como #ata3eader o
#ata0dapterA estos dos objetos los comentaremos ms adelante.
)n objeto &ommand lo 1amos a crear a partir de una cone(in ya e(istente, y 1a a contener una
sentencia 6LL para ejecutar sobre la cone(in establecida con el origen de datos.
Entre las propiedades que orecen los objetos 6ql&ommand y @le#b&ommand, caben destacar las
siguientes.
CommandTe5t+ &ontiene una cadena de te(to que 1a a indicar la sentencia 6LL o
procedimiento almacenado que se 1a a ejecutar sobre el origen de los datos.
CommandTimeout+ +iempo de espera en segundos que se 1a a aplicar a la ejecucin de un
objeto &ommand. 6u 1alor por deecto es de CF segundos.
CommandT(%e. %ndica el tipo de comando que se 1a a ejecutar contra el almac"n de datos, es
decir, indica como se debe interpretar el 1alor de la propiedad &ommad+e(t. !uede tener los
siguientes 1alores4 6tored!rocedure, para indicar que se trata de un procedimiento
almacenadoA +able#irect se trata de obtener una tabla por su nombre 7nicamente aplicable al
objeto @le#b&ommand8A y +e(t que indica que es una sentencia 6LL. EL 1alor por deecto es
+e(t.
Connection. #e1uel1e el objeto 6ql&onnection o @le#b&onnection utilizado para ejecutar el
objeto &ommand correspondiente.
Universidad Privada Telesup Pg. 24
Parameters. &oleccin de parmetros que se pueden utilizar para ejecutar el objeto
&ommand, esta coleccin se utiliza cuando deseamos ejecutar sentencias 6LL que hacen uso
de parmetros, esta propiedad de1uel1e un objeto de la clase 6ql!arameter&ollection o un
objeto de la clase @le#b!arameter&ollection. Estas colecciones contendrn objetos de la clase
6ql!aramter y @le#b!arameter, respecti1amente, para representar a cada uno de los
parmetros utilizados. Estos parmetros tambi"n son utilizados para ejecutar procedimientos
almacenados.
)na 1ez 1istas algunas de las propiedades de las clases 6ql&ommand y @le#b&ommand, 1amos a
pasar a comentar bre1emente los principales m"todos de estas clases.
CreateParameter. &rea un parmetro para el que despu"s podremos deinir una serie de
caracter$sticas espec$icas como pueden ser el tipo de dato, su 1alor, tamao, etc. #e1ol1er
un objeto de la clase 6ql!arameter u @le#b!arameter.
E5ecuteNon.uer(. Ejecuta la sentencia 6LL deinida en la propiedad &omand+e(t contra la
cone(in deinida en la propiedad &onnection. La sentencia a ejecutar debe ser de un tipo que
no de1uel1a un conjunto de registros, por ejemplo )pdate, #elete o %nsert. Este m"todo
de1uel1e un entero indicando el nmero de ilas que se han 1isto aectadas por la ejecucin
del objeto &ommand.
E5ecuteReader. Ejecuta la sentencia 6LL deinida en la propiedad &omand+e(t contra la
cone(in deinida en la propiedad &onnection. En este caso, la sentencia s$ de1ol1er un
conjunto de registros. El resultado de la ejecucin de este ser un objeto de la clase
6ql#ata3eaderM@le#b#ata3eader, que nos 1a a permitir leer y recorrer los resultados
de1ueltos por la ejecucin del objeto &ommand correspondiente.
E5ecute!calar. Este m"todo se utiliza cuando deseamos obtener la primera columna de la
primera ila del conjunto de registros, el resto de datos no se tendrn en cuenta. La utilizacin
de este m"todo tiene sentido cuando estamos ejecutando una sentencia 6LL del tipo 6elect
&ount7R8. Este m"todo de1uel1e un objeto de la clase gen"rica @bject.
Pre%are. Este m"todo construye una 1ersin compilada del objeto &ommand dentro del
almac"n de datos.
0 continuacin mostraremos algunos ejemplos de uso de objetos &ommand.
El &digo uente EG= ilustra la insercin de un registro utilizando un objeto 6ql&ommand. En primer
lugar utilizamos un constructor de la clase, que recibe como parmetro la sentencia a ejecutar y la
cone(in. &omo 1amos a ejecutar una sentencia que no produce un conjunto de resultados,
emplearemos el m"todo E(ecute*onLuery7 8. @bser1e tambi"n el lector en este ejemplo, que la
cone(in slo permanece abierta en el momento de ejecutar el comandoA esta es la t"cnica
recomendable que debemos utilizar para todas las operaciones con datos4 mantener abierta la cone(in
el menor tiempo posible.
' crear conexin
Dim oConexion As New SqlConnection()
oConexion.ConnectionString = "Server=(local);" & _
"Database=Gestion;uid=sa;pwd=;"
' crear sentencia SQL
Dim sSQL As String
sSQL = "INSERT INTO Clientes (IDCliente,Nombre,FIngreso) " & _
"VALUES(10,'Alfredo','18/7/2002')"
' crear comando
Dim oComando As New SqlCommand(sSQL, oConexion)
Dim iResultado As Integer
oConexion.Open() ' abrir conexin
iResultado = oComando.ExecuteNonQuery() ' ejecutar comando
oConexion.Close() ' cerrar conexin
MessageBox.Show("Registros aadidos:" & iResultado)
&digo uente EG=
En el &digo uente EG; realizamos tambi"n la insercin con un 6ql&ommand, pero utilizando en este
caso parmetros. En la cadena que tiene la sentencia 6LL indicaremos los parmetros con el ormato
ST*ombre!armetroU.
!ara crear cada uno de los parmetros utilizaremos la clase 6ql!arameter, mientras que para aadir los
parmetros usaremos la coleccin !armeters del objeto 6ql&ommand y su m"todo 0dd7 8.
3especto a la creacin de los parmetros, podemos obser1ar que es muy le(ible, ya que como 1emos
en este ejemplo, cada uno de ellos se crea de un modo distinto, especiicando el nombre, tipo de dato y
Universidad Privada Telesup Pg. 25
1alor.
' crear conexin
Dim oConexion As New SqlConnection()
oConexion.ConnectionString = "Server=(local);" & _
"Database=Gestion;uid=sa;pwd=;"
' crear sentencia SQL para insertar un registro con
' parmetros; indicamos el nombre del parmetro con
' @NombreParmetro
Dim sSQL As String
sSQL = "INSERT INTO Clientes (IDCliente,Nombre,FIngreso) " & _
"VALUES(@CodCli,@Nombre,@Fecha)"
' crear comando
Dim oComando As New SqlCommand(sSQL, oConexion)
' aadir parmetros al comando:
' parmetro primer campo
oComando.Parameters.Add(New SqlParameter("@CodCli", _
SqlDbType.Int))
oComando.Parameters("@CodCli").Value = 25
' parmetro segundo campo
oComando.Parameters.Add(New SqlParameter("@Nombre", "Raquel"))
' parmetro tercer campo
Dim oParametro As New SqlParameter()
oParametro.ParameterName = "@Fecha"
oParametro.SqlDbType = SqlDbType.DateTime
oParametro.Value = "25/10/2002"
oComando.Parameters.Add(oParametro)
Dim iResultado As Integer
oConexion.Open() ' abrir conexin
iResultado = oComando.ExecuteNonQuery() ' ejecutar comando
oConexion.Close() ' cerrar conexin
MessageBox.Show("Registros aadidos:" & iResultado)
&digo uente EG;
6i empleamos un objeto @le#b&ommand, la sinta(is de la sentencia 6LL cambia, ya que los
parmetros deberemos indicarlos como hac$amos en 0#@ clsico, utilizando el carcter SVU. :eamos
un ejemplo en el &digo uente EGC.
' crear el objeto de conexin
Dim oConexion As New OleDbConnection()
oConexion.ConnectionString = "Provider=SQLOLEDB;" & _
"Server=(local);Database=Gestion;uid=sa;pwd=;"
' crear sentencia SQL para modificar un registro con
' parmetros; indicamos el parmetro con ?
Dim sSQL As String
sSQL = "UPDATE Clientes SET Nombre = ? " & _
"WHERE IDCliente = 2"
Grupo EIDOS 36. Acceso a datos con ADO .NET
BCD
' crear comando
Dim oComando As New OleDbCommand(sSQL, oConexion)
oComando.Parameters.Add(New OleDbParameter("NombreCli", _
OleDbType.VarChar, 50))
oComando.Parameters("NombreCli").Value = "David"
Dim iResultado As Integer
oConexion.Open() ' abrir conexin
iResultado = oComando.ExecuteNonQuery() ' ejecutar comando
oConexion.Close() ' cerrar conexin
MessageBox.Show("Registros modificados:" & iResultado)
&digo uente EGC
Universidad Privada Telesup Pg. 26
En el caso de que necesitemos ejecutar un procedimiento almacenado, debemos indicarlo mediante las
propiedades &ommand+ype y &ommand+e(t del objeto &ommand que estemos utilizando. En la
primera establecemos el tipo de comando 7procedimiento almacenado8 seleccionando el 1alor de la
enumeracin asociada a la propiedadA y en la segunda asignamos una cadena con el nombre del
procedimiento almacenado. El &digo uente EG> muestra un ejemplo, en el que podemos comprobar
que hemos utilizado un constructor de 6ql&ommand sin parmetros, por lo que el objeto &onnection
lo asignamos despu"s mediante la propiedad &onnection
' crear conexin
Dim oConexion As New SqlConnection()
oConexion.ConnectionString = "Server=(local);" & _
"Database=Gestion;uid=sa;pwd=;"
' crear comando para ejecutar procedimiento almacenado
' que borra un registro
Dim oComando As New SqlCommand()
oComando.Connection = oConexion
oComando.CommandType = CommandType.StoredProcedure
oComando.CommandText = "BorraCli"
' aadir parmetro al comando
oComando.Parameters.Add(New SqlParameter("@IDCliente", _
SqlDbType.Int))
oComando.Parameters("@IDCliente").Value = 25
Dim iResultado As Integer
oConexion.Open() ' abrir conexin
iResultado = oComando.ExecuteNonQuery() ' ejecutar comando
oConexion.Close() ' cerrar conexin
MessageBox.Show("Registros borrados:" & iResultado)
&digo uente EG>
!ara obtener el resultado de una uncin del lenguaje 6LL, por ejemplo &ount7 8, emplearemos el
m"todo E(ecute6calar7 8 del objeto &ommand. En el &digo uente EGE, la ejecucin de este m"todo
nos de1uel1e el nmero de ilas de una tabla de la base de datos, que mostramos en un mensaje.
' crear conexin
Dim oConexion As New SqlConnection()
oConexion.ConnectionString = "Server=(local);" & _
"Database=Gestion;uid=sa;pwd=;"
' crear comando escalar
Dim sSQL As String
sSQL = "SELECT COUNT(*) FROM Clientes"
' crear comando
Dim oComando As New SqlCommand(sSQL, oConexion)
Dim iResultado As Integer
oConexion.Open() ' abrir conexin
iResultado = oComando.ExecuteScalar() ' ejecutar comando
oConexion.Close() ' cerrar conexin
MessageBox.Show("Nmero de registros de clientes:" & iResultado)
&digo uente EGE
Las clases DataReader
)n objeto #ata3eader permite la na1egacin hacia delante y de slo lectura, de los registros de1ueltos
por una consulta. Es lo ms parecido al objeto 3ecordset de 0#@ de tipo read onlyMor'ard only.
0 dierencia del resto de objetos, que siguen un esquema desconectado de manipulacin de datos, los
#ata3eader permanecen conectados durante todo el tiempo que realizan el recorrido por los registros
que contienen. Las clases que implementan este tipo de objeto son 6ql#ata3eader y
@le#b#ata3eader.
!ara obtener un #ata3eader, ejecutaremos el m"todo E(ecute3eader7 8 de un objeto &ommand basado
en una consulta 6LL o procedimiento almacenado.
0 continuacin 1amos a pasar a describir las principales propiedades de las clases 6ql#ata3eader y
Universidad Privada Telesup Pg. 27
@le#b#ata3eader.
ieldCount. #e1uel1e el nmero de columnas 7campos8 presentes en el ila 7registro8 actual.
IsClosed. #e1ol1er los 1alores +rue o ,alse, para indicar si el objeto #ata3eader est
cerrado o no.
Item. #e1uel1e en ormato nati1o, el 1alor de la columna cuyo nombre le indicamos como
$ndice en orma de cadena de te(to.
)na 1ez 1istas las propiedades, 1amos a comentar los m"todos ms destacables.
Close> ?. &ierra el objeto #ata3eader liberando los recursos correspondientes.
<et777> ?. El objeto #ata3eader presenta un conjunto de m"todos que nos 1an a permitir
obtener los 1alores de las columnas contenidas en el mismo en orma de un tipo de datos
determinado, segn el m"todo 2etKKK empleado. E(isten di1ersos m"todos 2etKKK
atendiendo al tipo de datos de la columna, algunos ejemplos son 2et5oolean78, 2et%ntC;78,
2et6tring78, 2et&har78, etc. &omo parmetro a este m"todo le debemos indicar el nmero de
orden de la columna que deseamos recuperar.
Ne5tResult> ?. #esplaza el puntero actual al siguiente conjunto de registros, cuando la
sentencia es un procedimiento almacenado de 6LL o una sentencia 6LL que de1uel1e ms de
un conjunto de registros, no debemos conundir este m"todo con el m"todo .o1e*e(t78 de
0#@, ya que en este caso no nos mo1emos al siguiente registro, sino al siguiente conjunto de
registros.
Read> ?. #esplaza el cursor actual al siguiente registro permitiendo obtener los 1alores del
mismo a tra1"s del objeto #ata3eader. Este m"todo de1ol1er +rue si e(isten ms registros
dentro del objeto #ata3eader, ,alse si hemos llegado al inal del conjunto de registros. La
posicin por deecto del objeto #ata3eader en el momento inicial es antes del primer registro,
por lo tanto para recorrer un objeto #ata3eader debemos comenzar con una llamada al m"todo
3ead78, y as$ situarnos en el primer registro.
El proyecto !ru#ata3eader 7hacer clic aqu$ para acceder al ejemplo8, contiene un ormulario con
algunos controles, que muestran el uso de objetos #ata3eader.
El botn Empleados crea a partir de un comando, un objeto #ata3eader que recorremos para llenar un
List5o( con los 1alores de una de las columnas de la tabla que internamente contiene el #ata3eader.
:eamos este caso en el &digo uente EGG.
Private Sub btnEmpleados_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnEmpleados.Click
' crear conexion
Dim oConexion As New SqlConnection()
oConexion.ConnectionString = "Server=(local);" & _
"Database=Northwind;uid=sa;pwd=;"
' crear comando
Dim oComando As New SqlCommand("SELECT * FROM Employees", _
oConexion)
' crear DataReader
Dim oDataReader As SqlDataReader
oConexion.Open()
oDataReader = oComando.ExecuteReader() ' obtener DataReader
' recorrer filas
While oDataReader.Read()
Me.lstEmpleados.Items.Add(oDataReader("LastName"))
End While
oDataReader.Close()
oConexion.Close()
End Sub
&digo uente EGG
&omo tambi"n hemos indicado anteriormente, un objeto &ommand puede estar basado en mltiples
sentencias 6LL, separadas por el carcter de punto y coma 7 A 8, que se ejecuten en lote. 0l crear un
#ata3eader desde un comando de este tipo, podemos recorrer el conjunto de consultas mediante el
m"todo *e(t3esult7 8 del #ata3eader. )n ejemplo de este tipo lo tenemos al pulsar el botn
&lientesM!roductos del ormulario, cuyo uente 1emos a continuacin en el &digo uente EG?.
@bser1e en este caso que conectamos a tra1"s de @LE #5, por lo que empleamos los objetos 0#@
.*E+ de esta categor$a.
Universidad Privada Telesup Pg. 28
#ro$ra"acin con %isual &asic .NET Grupo EIDOS
Private Sub btnCliProd_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnCliProd.Click
' crear conexion
Dim oConexion As New OleDbConnection()
oConexion.ConnectionString = "Provider=SQLOLEDB;" & _
"Server=(local);Database=Northwind;uid=sa;pwd=;"
' crear comando compuesto por varias consultas
Dim oComando As New OleDbCommand("SELECT * FROM Customers; SELECT * FROM
Products", oConexion)
Dim oDataReader As OleDbDataReader
oConexion.Open()
oDataReader = oComando.ExecuteReader() ' obtener DataReader
' recorrer filas de la primera consulta
While oDataReader.Read()
Me.lstClientes.Items.Add(oDataReader("CompanyName"))
End While
' pasar a la siguiente consulta y recorrer
' las filas
oDataReader.NextResult()
While oDataReader.Read()
Me.lstProductos.Items.Add(oDataReader("ProductName"))
End While
oDataReader.Close()
oConexion.Close()
End Sub
&digo uente EG?
La ,igura C>; muestra este ormulario despu"s de haber rellenado los controles List5o( usando
objetos #ata3eader.
Universidad Privada Telesup Pg. 29
Presentacin ( conte5tuali6acin+
Los temas que se tratan en la presente )nidad, tienen por inalidad que el estudiante realice
consultas de tablas relacionadas.
Com%etencia
Entiende la orma con se elabora las consultas de tablas relacionadas
0plica las dierentes clases con sus m"todos de implementacin.
&omprende cmo se utiliza las instrucciones %nner Qoin de 6elect.
Ca%acidades
!oder elaborar consultas de tablas relacionadas.
3ealiza almacenamiento de datos.
Elabora tipos de implementacin en las base de datos.
Actitudes
!articipa en las acti1idades de 2rupo
3espeta la opinin de los dems
Es responsable de los a1ances y producto inal
.uestra %nter"s y 1alora el curso en su ormacin proesional
.uestra disposicin y adaptacin para el trabajo en equipo
%n1estiga por iniciati1a propia
Ideas b:sicas ( contenidos esenciales de la Unidad+
La )nidad de 0prendizaje %4 &onsulta con cone(in a base de datos.
&onsultas4 0plicacin con tablas relacionadas
&lases #ata 3elatio. ."todos propiedades implementacin
Empleo de la clusula %nner Qoin. #e la instruccin 6elect de 6LL
!rocedimientos 0lmacenados, &oncepto, +ipos e %mplementacin
El control Data<rid& relaciones ( 3istas
Data<rid
Este control, del que ya realizamos una pequea demostracin en un apartado anterior, nos 1a a
permitir realizar enlace complejo de datos con 0#@ .*E+.
6e trata de la 1ersin mejorada del control #ata2rid de 0#@, disponible en :isual 5asic G, pero con
una serie de uncionalidades optimizadas, y otras nue1as aadidas.
!ara utilizar algunas de sus caracter$sticas, crearemos un proyecto de prueba con el nombre
#ata2rid!ru 7hacer clic aqu$ para acceder a este ejemplo8, consistente en un ormulario .#%, con una
serie de opciones de men, a tra1"s de las cuales, mostraremos di1ersas caracter$sticas de este control,
y algunas otras adicionales sobre 0#@ .*E+.
La opcin de men DataGrid ' Nor"al, mostrar el ormulario rm*ormal, que contiene un sencillo
#ata2rid con una tabla. !odemos editar los registros de la tabla y aadir nue1osA al trabajar en
descone(in, hasta que no pulsemos el botn 0ctualizar de este ormulario, el objeto #ata0dapter del
mismo no actualizar los datos del #ata6et hacia la base de datos $sica. @tra caracter$stica incluida
por deecto es la ordenacin de las ilas por columna al hacer clic en su t$tulo. ,inalmente, al
redimensionar el ormulario, tambi"n cambiar el tamao del #ata2rid, puesto que hemos utilizado su
propiedad 0nchor para anclarlo a todos los bordes de la 1entana. La ,igura CEF muestra este
ormulario.
CAP"TULO I0: CON!ULTA CON CONE7IONE! A -A!E DE DATO!
&onsultas4 0plicaciones con tablas relacionadas
Universidad Privada Telesup Pg. 30
,igura CEF. #ata2rid editable.
El &digo uente EB; muestra el cdigo principal de este ormulario. 3ecordamos al lector, la
necesidad de crear un objeto &ommand5uilder para el #ata0dapter, ya que en caso contrario, al
intentar actualizar el #ata6et contra la base de datos, se producir un error.
Private oDataAdapter As SqlDataAdapter
Private oDataSet As DataSet
Private Sub frmNormal_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles MyBase.Load
Private Sub frmNormal_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles MyBase.Load
' crear conexin
Dim oConexion As New SqlConnection()
oConexion.ConnectionString = "Server=(local);" & _
"Database=Musica;uid=sa;pwd=;"
' crear adaptador
oDataAdapter = New SqlDataAdapter("SELECT * FROM Grabaciones", oConexion)
' crear commandbuilder
Dim oCB As SqlCommandBuilder = New SqlCommandBuilder(oDataAdapter)
' crear dataset
oDataSet = New DataSet()
oDataAdapter.Fill(oDataSet, "Grabaciones")
' asignar dataset al datagrid
Me.grdDatos.DataSource = oDataSet
Me.grdDatos.DataMember = "Grabaciones"
End Sub
Private Sub btnActualizar_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnActualizar.Click
Me.oDataAdapter.Update(oDataSet, "Grabaciones")
End Sub
&digo uente EB;
Creacin de un Data<rid a tra39s de los asistentes del IDE
El modo ms potente de crear un #ata2rid es a tra1"s de cdigo, ya que nos permite un mayor grado
de manipulacin de sus propiedades.
6in embargo, para aquellas ocasiones en que necesitemos una 1ista rpida de los datos en un
ormulario para pruebas o similares, podemos utilizar los asistentes de :isual 6tudio .*E+, en lo que a
creacin de cone(iones, adaptadores, #ata2rid, etc., se reiere.
:amos a crear por lo tanto un nue1o ormulario para el proyecto con el nombre rm2rid0sist. )na 1ez
aadido el diseador, abriremos la pestaa E(plorador de servidores, y haciendo clic derecho en su
elemento !one(iones de datos, nos mostrar la 1entana para la creacin de una nue1a cone(in con
una base de datos, en este caso de un ser1idor 6LL 6er1erA en ella introduciremos los 1alores
Universidad Privada Telesup Pg. 31
necesarios para la cone(in. :er ,igura CE=.
,igura CE=. &reacin de una cone(in desde el E(plorador de ser1idores.
En el siguiente paso, abriremos el !uadro de )erra"ientas, y pulsaremos la icha #ata, aadiendo al
ormulario un control 6ql#ata0dapter, lo que abrir un asistente para la coniguracin de este control.
:er ,igura CE;.
Universidad Privada Telesup Pg. 32
+ras la 1entana de presentacin, al pulsar el botn 6iguiente, deberemos elegir la cone(in que el
adaptador utilizar. :er ,igura CEC.
,igura CE;. 0sistente para coniguracin del control 6ql#ata0dapter.
,igura CEC. 6eleccin de la cone(in de datos.
0 continuacin seleccionaremos el tipo de consulta, en este caso una sencilla sentencia 6LL. :er
,igura CE>.
Universidad Privada Telesup Pg. 33
,igura CE>. 6eleccin del tipo de consulta que contendr el adaptador.
&ontinuaremos con la escritura de la sentencia 6LL que quedar incluida en el #ata0dapter. :er
,igura CEE.
,igura CEE. Escritura de la consulta 6LL a generar.
&omo paso inal, se muestra un resumen de lo que este asistente ha generado en el #ata0dapter.
,igura CEG.
Universidad Privada Telesup Pg. 34
,igura CEG. 3esultados del asistente de generacin del #ata0dapter.
,inalizada la creacin del adaptador de datos, seleccionaremos el men #atos J 2enerar conjunto de
datos del %#E, que nos mostrar una 1entana en la que daremos el nombre del #ata6et que utilizar el
ormulario, y nos permitir elegir las tablas que contendr. :er ,igura CE?.
,igura CE?. &reacin del #ata6et.
0 continuacin dibujaremos un #ata2rid en el ormulario, y pasaremos a su 1entana de propiedades.
En la propiedad #ata6ource asignaremos el #ata6et que acabamos de crear, mientras que en la
propiedad #ata.ember, seleccionaremos la tabla del #ata6et que 1a a mostrar el #ata2rid. :er
,igura CEB.
,igura CEB. !ropiedades del #ata2rid para la obtencin de datos.
&ompletado este ltimo paso, el #ata2rid mostrar en tiempo de diseo, la disposicin de las
columnas de la tabla en su interior. :er ,igura CE<.
Universidad Privada Telesup Pg. 35
,igura CE<. #ata2rid mostrando inormacin de las columnas de la tabla del #ata6et.
En cuanto al cdigo que debemos escribir, en el e1ento Load, inicializaremos el #ata6et, rellenndolo
a continuacin mediante el #ata0dapter. :er &digo uente EBC.
Private Sub frmGridAsist_Load(ByVal sender As Object, ByVal e As
System.EventArgs)
Handles MyBase.Load
Me.DsMusica1.Clear()
Me.SqlDataAdapter1.Fill(Me.DsMusica1)
End Sub
&digo uente EBC
!odremos 1er este ormulario en ejecucin al seleccionar en el ormulario principal del ejemplo, el
men DataGrid ' Asistente.
Con=igurar las %ro%iedades del Data<rid
En los casos anteriores, hemos creado un ormulario con un #ata2rid que ten$a la apariencia 1isual
por deecto de este control. E1identemente, a tra1"s de las propiedades del #ata2rid, tanto en diseo
como en ejecucin, podemos de un modo muy le(ible y potente, cambiar la apariencia y el
comportamiento de este control.
En el ormulario rm2rid!rop, mostramos la misma inormacin que en el anterior ejemplo, pero con
una presentacin totalmente distinta, al modiicar algunas propiedades del #ata2rid como 5ac-&olor,
0lternating5ac-&olor, &aption+e(t, etc. 0briremos este ormulario con la opcin DataGrid '
#ropiedades, de la 1entana .#% del proyecto. :er ,igura CGF.
,igura CGF. #ata2rid con propiedades modiicadas.
Con=igurar %or cdigo las %ro%iedades del Data<rid
Universidad Privada Telesup Pg. 36
6upongamos ahora, que necesitamos por cdigo modiicar las propiedades no slo del #ata2rid en
general, sino de algunas columnas del mismo. Esto es perectamente actible mediante los objetos
manipuladores de estilo, tanto del propio #ata2rid, como de cada una de las columnas que lo
componen.
La clase #ata2rid+able6tyle, nos permitir crear objetos que contengan una coniguracin de tabla
personalizada, que despu"s aadiremos al #ata2rid.
!or otra parte, mediante la clase #ata2rid+e(t5o(&olumn, crearemos objetos con la coniguracin
particular para cada columna. La propiedad cla1e de estos objetos es .apping*ame, que contiene una
cadena con el nombre de la columna de la tabla del #ata6et, que ser la que muestre dicha columna.
El ormulario rm2rid!rop&od que abriremos con la opcin de men DataGrid ' #rop.cdi$o, hace
uso en el e1ento de carga de la 1entana, de estos objetos para 1ariar el aspecto por deecto que tiene su
#ata2rid. El &digo uente EB> muestra las instrucciones empleadas.
Private Sub frmGridPropCod_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyBase.Load
' crear conexin
Dim oConexion As New SqlConnection()
oConexion.ConnectionString = "Server=(local);" & _
"Database=Musica;uid=sa;pwd=;"
' crear adaptador
oDataAdapter = New SqlDataAdapter("SELECT * FROM Grabaciones", oConexion)
' crear commandbuilder
Dim oCB As SqlCommandBuilder = New SqlCommandBuilder(oDataAdapter)
' crear dataset
oDataSet = New DataSet()
oDataAdapter.Fill(oDataSet, "Grabaciones")
' asignar dataset al datagrid
Me.grdDatos.DataSource = oDataSet
Me.grdDatos.DataMember = "Grabaciones"
' configurar grid por cdigo
Me.grdDatos.Anchor = AnchorStyles.Bottom + AnchorStyles.Left +
AnchorStyles.Right + AnchorStyles.Top
Me.grdDatos.CaptionText = "El listado de las grabaciones"
Me.grdDatos.CaptionBackColor = Color.Turquoise
Me.grdDatos.CaptionForeColor = Color.Black
' crear un objeto para estilos del datagrid
Dim oEstiloGrid As New DataGridTableStyle()
oEstiloGrid.MappingName = "Grabaciones"
oEstiloGrid.BackColor = Color.LightGoldenrodYellow
oEstiloGrid.AlternatingBackColor = Color.Aquamarine
' crear objetos de columna-grid para cada
' columna de la tabla a mostrar en el datagrid
Dim oColGrid As DataGridTextBoxColumn
' configurar cada objeto de columna-grid
oColGrid = New DataGridTextBoxColumn()
oColGrid.TextBox.Enabled = False
oColGrid.Alignment = HorizontalAlignment.Center
oColGrid.HeaderText = "Descripcin grabac."
' nombre de la columna del dataset que
' se mapea hacia esta columna del grid
oColGrid.MappingName = "Titulo"
oColGrid.Width = 300
' aadir la columna al objeto que contiene
' los estilos del datagrid, en concreto,
' a la coleccin de estilos de columna
oEstiloGrid.GridColumnStyles.Add(oColGrid)
oColGrid = Nothing
oColGrid = New DataGridTextBoxColumn()
oColGrid.TextBox.Enabled = False
oColGrid.Alignment = HorizontalAlignment.Left
Universidad Privada Telesup Pg. 37
oColGrid.HeaderText = "Fecha COMPRA"
oColGrid.MappingName = "FCompra"
oColGrid.Width = 110
oColGrid.Format = "ddd, d-MMM-yyy"
oEstiloGrid.GridColumnStyles.Add(oColGrid)
oColGrid = Nothing
oColGrid = New DataGridTextBoxColumn()
oColGrid.TextBox.Enabled = False
oColGrid.Alignment = HorizontalAlignment.Right
oColGrid.HeaderText = "Valor pagado"
oColGrid.MappingName = "Precio"
oColGrid.Width = 85
oColGrid.Format = "#,#"
oEstiloGrid.GridColumnStyles.Add(oColGrid)
oColGrid = Nothing
' una vez creadas todas las columnas de
' estilos para el grid, aadir el objeto
' que contiene el estilo personalizado
' a la coleccin de estilos de tablas
' del datagrid
Me.grdDatos.TableStyles.Add(oEstiloGrid)
End Sub
&digo uente EB>
La ,igura CG= muestra el resultado de esta modiicacin sobre el #ata2rid.
,igura CG=. #ata2rid modiicado totalmente por cdigo.
!eleccin de tabla en el Data<rid
0l construir un #ata6et, podemos utilizar distintos objetos #ata0dapter para rellenarlo con di1ersas
tablas. &omo hemos 1isto en los anteriores ejemplos, para mostrar datos en un #ata2rid, debemos
asignar el #ata6et a su propiedad #ata6ource, y el nombre de la tabla a mostrar en la propiedad
#ata.ember. 6in embargo, si ob1iamos la asignacin a #ata.ember, gracias a los mecanismos de
#ata 5inding, el propio #ata2rid, nos orecer la oportunidad de seleccionar la tabla a mostrar.
El ormulario rm2rid+ablas, que abrimos mediante la opcin de men DataGrid ' %arias talas del
proyecto de ejemplo, dispone de este comportamiento. En su e1ento Load crearemos dos #ata0dapter
que usaremos para llenar un #ata6et. :er &digo uente EBE.
Private Sub frmGridTablas_Load(ByVal sender As Object, ByVal e As
System.EventArgs)
Handles MyBase.Load
' crear conexin
Dim oConexion As New SqlConnection()
Universidad Privada Telesup Pg. 38
oConexion.ConnectionString = "Server=(local);" & _
"Database=Musica;uid=sa;pwd=;"
' crear adaptadores
Dim oDAAutores As New SqlDataAdapter("SELECT * FROM Autores", oConexion)
Dim oDAGrabaciones As New SqlDataAdapter("SELECT * FROM Grabaciones",
oConexion)
' crear dataset
Dim oDataSet As New DataSet()
oDAAutores.Fill(oDataSet, "Autores")
oDAGrabaciones.Fill(oDataSet, "Grabaciones")
' asignar dataset a datagrid
Me.grdDatos.DataSource = oDataSet
End Sub
&digo uente EBE
&omo al asignar el #ata6et al #ata2rid no hemos indicado qu" tabla queremos que muestre, el
#ata2rid en el ormulario 1isualizar un nodo que al e(pandir, nos permitir seleccionar la tabla a
mostrar. !odremos contraer dicha tabla para seleccionar otra, y as$ sucesi1amente. :er ,igura CG;.
,igura CG;. 6eleccin de tabla a mostrar en un #ata2rid,
Relaciones entre tablas mediante ob*etos DataRelation
Los objetos #ata3elation nos permiten establecer una relacin entre dos tablas 7objetos #ata+able8 de
un #ata6et, a tra1"s de una columna o campo comn 7objetos #ata&olumn8.
!ara demostrar la creacin de relaciones con estos objetos, utilizaremos el proyecto de ejemplo
3elacionar#atos 7hacer clic aqu$ para acceder a este ejemplo8, en el que a tra1"s de un ormulario
.#%, crearemos 1arios ormularios hijos, cada uno con un tipo de relacin.
Obtener tablas relacionadas mediante cdigo
En primer lugar, la opcin de men *elacionar ' +anual, muestra el ormulario rm.anual, en el que
al cargar el ormulario, creamos una relacin entre dos tablas, &ustomers y @rders, por un campo
cla1e. #espu"s llenamos un &ombo5o( con datos de la tabla &ustomers.
0l seleccionar un 1alor del &ombo5o(, se tomarn las ilas relacionadas de la tabla @rders y se llenar
con ellas un List5o(. El cdigo necesario podemos 1erlo en el &digo uente EBG.
Private Sub frmManual_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Handles MyBase.Load
' crear conexin
Dim oConexion As New SqlConnection()
oConexion.ConnectionString = "server=(local);" & _
"database=Northwind;uid=sa;pwd=;"
' crear adaptadores
Dim daCustomers As New SqlDataAdapter("SELECT * FROM Customers", oConexion)
Dim daOrders As New SqlDataAdapter("SELECT * FROM Orders", oConexion)
' instanciar dataset
oDataSet = New DataSet()
oConexion.Open()
Universidad Privada Telesup Pg. 39
' utilizar los dataadapters para llenar el dataset con tablas
daCustomers.Fill(oDataSet, "Customers")
daOrders.Fill(oDataSet, "Orders")
oConexion.Close()
' relacionar las dos tablas del dataset por campo comn
oDataSet.Relations.Add("Customers_Orders", _
oDataSet.Tables("Customers").Columns("CustomerID"), _
oDataSet.Tables("Orders").Columns("CustomerID"))
' llenar el combobox con los nombres de cliente
Dim oDataRow As DataRow
For Each oDataRow In oDataSet.Tables("Customers").Rows
Me.cboCustomers.Items.Add(oDataRow("CustomerID") & _
"-" & oDataRow("CompanyName"))
Next
End Sub
' cada vez que se selecciona un valor en el combo
' se produce este evento
Private Sub cboCustomers_SelectedIndexChanged(ByVal sender As Object, ByVal e
As
System.EventArgs) Handles cboCustomers.SelectedIndexChanged
' limpiar los valores del listbox
Me.lstOrders.Items.Clear()
Dim drFilaPadre As DataRow
' obtener la fila de la tabla maestra: Customers
drFilaPadre = oDataSet.Tables("Customers").Rows(Me.cboCustomers.SelectedIndex)
Dim drFilasHijas() As DataRow
' obtener las filas hijas de la tabla Orders,
' gracias a la relacin Customers-Orders
drFilasHijas = drFilaPadre.GetChildRows("Customers_Orders")
Dim drFila As DataRow
' rellenar el listbox con valores de las filas hijas
For Each drFila In drFilasHijas
Me.lstOrders.Items.Add(drFila("CustomerID") & _
"-" & drFila("OrderID") & _
"-" & drFila("OrderDate"))
Next
End Sub
&digo uente EBG
La ,igura CGC muestra este ormulario.
,igura CGC. @btencin de ilas relacionadas de orma manual.

Vous aimerez peut-être aussi