Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Acceso A Datos Con ADO
Acceso A Datos Con ADO
NET
En los siguientes temas vamos a tratar el acceso a datos desde VB.NET, haciendo uso del nuevo modelo de acceso a datos incluido en la plataforma .NET Framework: A ! .NET. "ostraremos las tareas #$sicas para el acceso a datos desde aplicaciones #asadas en formularios %indows, empleando la tecnolog&a proporcionada por A ! .NET. A ! .NET es la nueva versi'n del modelo de o#(etos A ! )Active* ata !#(ects+, es decir, la estrategia ,ue ofrece "icrosoft para el acceso a datos. A ! .NET ha sido ampliado para cu#rir todas las necesidades ,ue A ! no ofrec&a, - est$ dise.ado para tra#a(ar con con(untos de datos desconectados, lo ,ue permite reducir el tr$fico de red. A ! .NET utili/a *"0 como formato universal de transmisi'n de los datos. A ! .NET posee una serie de o#(etos ,ue son los mismos ,ue aparecen en la versi'n anterior de A !, como pueden ser el o#(eto 1onnection o 1ommand, e introduce nuevos o#(etos tales como el o#(eto ata2eader, ata3et o ataView. A ! .NET se puede definir como: 4n con(unto de interfaces, clases, estructuras - enumeraciones ,ue permiten el acceso a datos desde la plataforma .NET de "icrosoft 0a evoluci'n l'gica del A56 A ! tradicional de "icrosoft 5ermite un modo de acceso desconectado a los datos, los cuales pueden provenir de m7ltiples fuentes de datos, de diferente ar,uitectura de almacenamiento 3oporta un completo modelo de programaci'n - adaptaci'n, #asado en el est$ndar *"0 3eguidamente vamos a reali/ar una descripci'n gen8rica de la ar,uitectura de A ! .NET, - m$s tarde veremos como utili/arlo desde aplicaciones VB.NET
datos cada ve/ ,ue avan/amos un registro para recoger la informaci'n asociada a ese registro )condiciones del (oin+. 5ara solucionarlo, lo ,ue se reali/a es almacenar temporalmente toda la informaci'n necesaria donde sea necesario - tra#a(ar con ella. Esto es lo ,ue representa un ata3et en el modelo A ! .NET. 4n ata3et es una cach8 de registros recuperados de una #ase de datos ,ue act7a como un sistema de almacenamiento virtual, - ,ue contiene una o m$s ta#las #asadas en las ta#las reales de la #ase de datos. Adicionalmente, almacena las relaciones - reglas de integridad e9istentes entre ellas para garanti/ar la esta#ilidad e integridad de la informaci'n de la #ase de datos. "u- importante es recalcar, ,ue los ata3ets son almacenes pasivos de datos, esto es, no se ven alterados ante cam#ios su#-acentes de la #ase de datos. Es necesario recargarlos siempre ,ue ,ueramos estar al da, en cuanto a datos se refiere. 4na de las ma-ores venta(as de esta implementaci'n, es ,ue una ve/ o#tenido el ata3et, 8ste puede ser enviado )en forma de flu(o *"0+ entre distintos componentes de la capa de negocio, como si de una varia#le m$s se tratase, ahorrando as& comunicaciones a trav8s de la #ase de datos. 4na consecuencia l'gica de este tipo de ar,uitecturas, es la de conseguir ,ue los ata3ets sean independientes de los or&genes de datos. 0os drivers !0E: B transformar$n la consulta 3;0 en un cursor representado con una estructura *"0, ,ue es independiente del motor de la #ase de datos. Esto nos permitir$ tra#a(ar con m7ltiples or&genes de datos, de distintos fa#ricante e incluso en formatos ,ue no pertene/can a #ases de datos, por e(emplo, ficheros planos u ho(as de c$lculo, lo ,ue representa un importante punto de compati#ilidad - fle9i#ilidad. 3i a esto unimos el hecho de ,ue disponemos de un modelo consistente de o#(etos )9ml !"+ ,ue es independiente del origen de datos, las operaciones de los ata3ets no se ver$n afectadas por dicho origen. 0a persistencia es un concepto mu- interesante en el mundo del desarrollo. Es un mecanismo por el cual un componente puede almacenar su estado )valores de varia#les, propiedades, datos...en un momento concreto del tiempo+ en un soporte de almacenamiento fi(o. e manera, ,ue cuando es necesario, se puede recargar el componente tal - como ,ued' en una operaci'n anterior. En un sistema de tra#a(o !ff:0ine como el ,ue plantea A ! .NET, la persistencia es un mecanismo fundamental. 5odemos cerrar la aplicaci'n - mantener persistentes todos los ata3ets necesarios, de manera ,ue al reiniciarla, nos encontramos los ata3ets tal - como los de(amos. Ahorrando el tiempo ,ue hu#iera sido necesario para recuperar de nuevo toda esa informaci'n del servidor. !ptimi/ando todav&a m$s el rendimiento del sistema distri#uido. El formato ,ue emplea A ! .NET para almacenar su estado es *"0. 5uesto ,ue -a es un est$ndar de la industria, esta persistencia nos ofrece las siguientes cualidades: 0a informaci'n puede estar accesi#le para cual,uier componente del sistema ,ue entienda *"0. Es un formato de te9to plano, no #inario, ,ue lo hace compati#le con cual,uier componente de cual,uier plataforma, - recupera#le en cual,uier circunstancia.
DataSet
El A56 de A ! .NET proporciona una superclase, ata3et, ,ue encapsula lo ,ue ser&a la #ase de datos a un nivel l'gico: ta#las, vistas, relaciones, integridad entre todos ellos, etc., pero siempre con independencia del tipo de fa#ricante ,ue la dise.'. A,u& se tiene el me(or concepto de datos desconectados: una copia en el cliente de la ar,uitectura de la #ase de datos, #asada en un es,uema *"0 ,ue la independi/a del fa#ricante, proporcionando al desarrollador la li#ertad de tra#a(o
independiente de la plataforma. 0a Figura <<= muestra una representaci'n de este tipo de o#(eto.
Es,uema de un ata3et.
Esta clase se compone a su ve/, de clases de soporte, ,ue representan cada una, los elementos ar,uitecturales de la #ase de datos: ta#las, columnas, filas, sus reglas de che,ueo, sus relaciones, las vistas asociadas a la ta#la, etc.
A ! .NET es el modelo de o#(etos para el acceso a datos incluido en la (erar,u&a de clases de la plataforma .NET Framework. 3e trata de una evoluci'n de A !, el anterior modelo para la gesti'n de datos, incluido en VBA. A ! .NET ha sido ampliado para cu#rir todas las necesidades ,ue A ! no ofrec&a. Est$ dise.ado para tra#a(ar con con(untos de datos desconectados, lo ,ue permite reducir el tr$fico de red, utili/ando *"0 como formato universal de transmisi'n de los datos. A ! .NET posee una serie de o#(etos ,ue son los mismos ,ue aparecen en la versi'n anterior de A !, como pueden ser el o#(eto 1onnection o 1ommand, e introduce nuevos o#(etos tales como el o#(eto ata2eader, ata3et o ataView. A continuaci'n vamos a comentar #revemente los o#(etos principales ,ue posee A ! .NET. 0os espacios de nom#re ,ue utili/a A ! .NET son principalmente 3-stem. ata 3-stem. ata.!le # o 3-stem. ata.3,l1lient. 3-stem. ata ofrece las facilidades de codificaci'n para el acceso - mane(o de datos, mientras ,ue 3-stem. ata.!le # - 3-stem. ata.3,l1lient contienen los proveedores> en el primer caso, los proveedores gen8ricos de !0E B, - en el segundo, los proveedores nativos de 3;0 3erver ,ue ofrece la plataforma .NET. 5ara el lector ,ue ha-a seguido la evoluci'n de la plataforma .NET, de#emos puntuali/ar ,ue estos espacios de nom#res se denomina#an 3-stem. ata.A ! - 3-stem. ata.3;0 en la Beta B de la plataforma .NET. El o#(eto 1onnection define el modo en c'mo se esta#lece la cone9i'n con el almac8n de datos. .NET Framework ofrece dos o#(etos 1onnection: 3,l1onnection - !le #1onnection, ,ue se corresponden con las dos posi#ilidades de proveedores ,ue disponemos. !tro o#(eto importante dentro del modelo de o#(etos de A ! .NET es el o#(eto 3-stem. ata. ata3et )con(unto de datos+. Este nuevo o#(eto representa un con(unto de datos de manera completa, pudiendo incluir m7ltiples ta#las (unto con sus relaciones. No de#emos confundir el nuevo o#(eto ata3et con el antiguo o#(eto 2ecordset> el o#(eto ata3et contiene un con(unto de ta#las - las relaciones entre las mismas, sin em#argo el o#(eto 2ecordset contiene 7nicamente una ta#la. 5ara acceder a una ta#la determinada el o#(eto ata3et ofrece la colecci'n Ta#les. 5ara poder crear e iniciali/ar las ta#las del ata3et de#emos hacer uso del o#(eto ataAdapter, ,ue igualmente, posee las dos versiones, es decir, el o#(eto 3,l ataAdapter para 3;0 3erver !le # ataAdapter gen8rico de !0E B. En la Beta B de la plataforma .NET el o#(eto ataAdapter se denomina#a ata3et1ommand. Al o#(eto ataAdapter le pasaremos como par$metro una cadena ,ue representa la consulta ,ue se va a e(ecutar - ,ue va a rellenar de datos el ata3et. el o#(eto ataAdapter utili/aremos el m8todo Fill)+, ,ue posee dos par$metros, el primero es el o#(eto ata3et ,ue vamos rellenar con datos, - el segundo es una cadena ,ue identifica el o#(eto ataTa#le )ta#la+ ,ue se va a crear dentro del o#(eto ata3et como resultado de la e(ecuci'n de la consulta . 4n ata3et puede contener diversas ta#las, ,ue se representan mediante o#(etos ataTa#le. 5ara mostrar el contenido de un ata3et, mediante ata Binding, por e(emplo, necesitamos el o#(eto ataView. 4n o#(eto ataView nos permite o#tener un su#con(unto personali/ado de los datos contenidos en un o#(eto ataTa#le. 1ada o#(eto ataTa#le de un ata3et posee la propiedad efaultView, ,ue devuelve la vista de los datos por defecto de la ta#la.
!tro o#(eto de A ! .NET es ata2eader, ,ue representa un cursor de s'lo lectura - ,ue s'lo permite despla/amiento hacia adelante )read:onl-Cforward:onl-+, cada ve/ e9iste un 7nico registro en memoria, el o#(eto ata2eader mantiene a#ierta la cone9i'n con el origen de los datos hasta ,ue es cerrado. Al igual ,ue ocurr&a con otros o#(etos de A ! .NET, de este o#(eto tenemos dos versiones, ,ue como el lector sospechar$ se trata de los o#(etos 3,l ata2eader - !le # ata2eader.
Data"olu nMapping. V&nculo l'gico e9istente entre una columna de un o#(eto del ata3et - la columna f&sica de la ta#la de la #ase de datos. DataTa!leMapping. V&nculo l'gico e9istente entre una ta#la del ata3et - la ta#la f&sica de la #ase de datos.
Adem$s de estas clases, e9iste otro grupo de clases consistente en las clases espec&ficas de un proveedor de datos.
Estas clases conforman los aspectos particulares de un fa#ricante de proveedores de datos .NET. Tienen una sinta9is con el formato ***1lase, donde E***F es un prefi(o ,ue determina el tipo de plataforma de cone9i'n a datos. 3e definen en dos espacios de nom#re: 3-stem. ata.3,l1lient - 3-stem. ata.!le #. escripci'n de las clases ,ue podemos encontrar en estos espacios de Nom#re:
5ara a,uellos conocedores de A ! en alguna de sus versiones anteriores, podemos hacer una analog&a o comparaci'n entre las antiguas clases de A ! - las nuevas de A ! .NET.
1omparativa entre las clases de A ! - A ! .NET.
Gasta a,u& hemos reali/ado una introducci'n a la tecnolog&a A ! .NET, repasando su ar,uitectura comentando las clases principales. En lo ,ue resta de tema vamos a utili/ar las distintas clases ,ue nos ofrece A ! .NET desde VB.NET, para reali/ar tareas comunes de acceso a datos, como pueden ser esta#lecer una cone9i'n, o#tener un con(unto de registros, reali/ar operaciones con los datos, etc.
!le #1onnection+, se a#rir$ la cone9i'n ,ue se ha indicado en su propiedad 1onnection3tring, es decir, esta propiedad indicar$ la cadena de cone9i'n ,ue se va a utili/ar para esta#lecer la cone9i'n con el almac8n de datos correspondiente. El m8todo !pen)+ no posee par$metros. El constructor de la clase 1onnection )al decir clase 1onnection de forma gen8rica nos estamos refiriendo en con(unto a las clases 3,l1onnection - !le #1onnection de A ! .NET+ se encuentra so#recargado, - en una de sus versiones reci#e como par$metro una cadena ,ue ser$ la cadena de cone9i'n ,ue se apli,ue a su propiedad 1onnection3tring. 3i hacemos uso de la clase 3,l1onnection, en la cadena de cone9i'n no podremos especificar una 3N de ! B1, -a ,ue la cone9i'n se va a reali/ar en este caso directamente con 3;0 3erver. I si utili/amos la clase !le #1onnection de#emos especificar el proveedor !0E B ,ue se va a utili/ar para esta#lecer la cone9i'n, una e9cepci'n es el proveedor !0E B para ! B1 )"3 A3;0+, ,ue no puede ser utili/ado, -a ,ue el proveedor !0E B de .NET no soporta el proveedor de ! B1, en este caso de#eremos reali/ar la cone9i'n utili/ando el proveedor adecuado al almac8n de datos. 0os proveedores !0E B ,ue son compati#les con A ! .NET son: 3;0!0E B: "icrosoft !0E B 5rovider for 3;0 3erver. "3 A!2A: "icrosoft !0E B 5rovider for !racle. "icrosoft.Jet.!0E B.?.@: !0E B 5rovider for "icrosoft Jet. 0a sinta9is utili/ada para indicar la cadena de cone9i'n, con las particularidades propias de cada proveedor, veremos ,ue es mu- similar a la utili/ada en A ! cl$sico. El 1'digo fuente KK= muestra un e(emplo de cone9i'n con un servidor 3;0 3erver H@@@, - su posterior descone9i'n, utili/ando un o#(eto 3,l1onnection. e#emos importar el espacio de nom#res ata.3,l1lient para poder utili/ar el o#(eto. Este c'digo lo podemos asociar a la pulsaci'n de un #ot'n en un formulario.
El 1'digo fuente KA@ muestra la misma operaci'n pero usando el o#(eto de cone9i'n para el proveedor de !0E B. !#serve el lector las diferencias en las cadenas de cone9i'n - el o#(eto de e9cepci'n con respecto al anterior e(emplo, as& como el espacio de nom#res a importar.
and
Esta#lecida una cone9i'n con un almac8n de datos, la siguiente operaci'n l'gica consiste en enviarle sentencias para reali/ar los distintos tipos de operaciones ,ue ha#itualmente reali/amos con los datos. 0as clases 1ommand de A ! .NET ser$n las usaremos para reali/ar tales operaciones. 3,l1ommand - !le #1ommand, son mu- similares al o#(eto 1ommand e9istente en A !. El o#(eto 1ommand nos va a permitir e(ecutar una sentencia 3;0 o un procedimiento almacenado so#re la fuente de datos a la ,ue estamos accediendo. A trav8s de un o#(eto 1ommand tam#i8n podremos o#tener un con(unto de resultados del almac8n de datos. En este caso, los resultados se pasar$n a otros o#(etos de A ! .NET, como ata2eader o ataAdapter> estos dos o#(etos los comentaremos m$s adelante. 4n o#(eto 1ommand lo vamos a crear a partir de una cone9i'n -a e9istente, - va a contener una sentencia 3;0 para e(ecutar so#re la cone9i'n esta#lecida con el origen de datos. Entre las propiedades ,ue ofrecen los o#(etos 3,l1ommand - !le #1ommand, ca#en destacar las siguientes. "o andTe&t. 1ontiene una cadena de te9to ,ue va a indicar la sentencia 3;0 o procedimiento almacenado ,ue se va a e(ecutar so#re el origen de los datos. "o andTi eout. Tiempo de espera en segundos ,ue se va a aplicar a la e(ecuci'n de un o#(eto 1ommand. 3u valor por defecto es de <@ segundos. "o andType. 6ndica el tipo de comando ,ue se va a e(ecutar contra el almac8n de datos, es decir, indica como se de#e interpretar el valor de la propiedad 1ommadTe9t. 5uede tener los siguientes valores: 3tored5rocedure, para indicar ,ue se trata de un procedimiento almacenado> Ta#le irect se trata de o#tener una ta#la por su nom#re )7nicamente aplica#le al o#(eto !le #1ommand+> - Te9t ,ue indica ,ue es una sentencia 3;0. E0 valor por defecto es Te9t. "onnection. evuelve el o#(eto 3,l1onnection o !le #1onnection utili/ado para e(ecutar el o#(eto 1ommand correspondiente.
'ara eters. 1olecci'n de par$metros ,ue se pueden utili/ar para e(ecutar el o#(eto 1ommand, esta colecci'n se utili/a cuando deseamos e(ecutar sentencias 3;0 ,ue hacen uso de par$metros, esta propiedad devuelve un o#(eto de la clase 3,l5arameter1ollection o un o#(eto de la clase !le #5arameter1ollection. Estas colecciones contendr$n o#(etos de la clase 3,l5aramter - !le #5arameter, respectivamente, para representar a cada uno de los par$metros utili/ados. Estos par$metros tam#i8n son utili/ados para e(ecutar procedimientos almacenados. 4na ve/ vistas algunas de las propiedades de las clases 3,l1ommand - !le #1ommand, vamos a pasar a comentar #revemente los principales m8todos de estas clases. "reate'ara eter. 1rea un par$metro para el ,ue despu8s podremos definir una serie de caracter&sticas espec&ficas como pueden ser el tipo de dato, su valor, tama.o, etc. evolver$ un o#(eto de la clase 3,l5arameter u !le #5arameter. E&ecuteNon(uery. E(ecuta la sentencia 3;0 definida en la propiedad 1omandTe9t contra la cone9i'n definida en la propiedad 1onnection. 0a sentencia a e(ecutar de#e ser de un tipo ,ue no devuelva un con(unto de registros, por e(emplo 4pdate, elete o 6nsert. Este m8todo devuelve un entero indicando el n7mero de filas ,ue se han visto afectadas por la e(ecuci'n del o#(eto 1ommand. E&ecute$eader. E(ecuta la sentencia 3;0 definida en la propiedad 1omandTe9t contra la cone9i'n definida en la propiedad 1onnection. En este caso, la sentencia s& devolver$ un con(unto de registros. El resultado de la e(ecuci'n de este ser$ un o#(eto de la clase 3,l ata2eaderC!le # ata2eader, ,ue nos va a permitir leer - recorrer los resultados devueltos por la e(ecuci'n del o#(eto 1ommand correspondiente. E&ecuteScalar. Este m8todo se utili/a cuando deseamos o#tener la primera columna de la primera fila del con(unto de registros, el resto de datos no se tendr$n en cuenta. 0a utili/aci'n de este m8todo tiene sentido cuando estamos e(ecutando una sentencia 3;0 del tipo 3elect 1ount)L+. Este m8todo devuelve un o#(eto de la clase gen8rica !#(ect. 'repare. Este m8todo constru-e una versi'n compilada del o#(eto 1ommand dentro del almac8n de datos. A continuaci'n mostraremos algunos e(emplos de uso de o#(etos 1ommand. El 1'digo fuente KAB ilustra la inserci'n de un registro utili/ando un o#(eto 3,l1ommand. En primer lugar utili/amos un constructor de la clase, ,ue reci#e como par$metro la sentencia a e(ecutar - la cone9i'n. 1omo vamos a e(ecutar una sentencia ,ue no produce un con(unto de resultados, emplearemos el m8todo E9ecuteNon;uer-) +. !#serve tam#i8n el lector en este e(emplo, ,ue la cone9i'n s'lo permanece a#ierta en el momento de e(ecutar el comando> esta es la t8cnica recomenda#le ,ue de#emos utili/ar para todas las operaciones con datos: mantener a#ierta la cone9i'n el menor tiempo posi#le.
En el 1'digo fuente KAH reali/amos tam#i8n la inserci'n con un 3,l1ommand, pero utili/ando en este caso par$metros. En la cadena ,ue tiene la sentencia 3;0 indicaremos los par$metros con el formato MNNom#re5ar$metroO. 5ara crear cada uno de los par$metros utili/aremos la clase 3,l5arameter, mientras ,ue para a.adir los par$metros usaremos la colecci'n 5ar$meters del o#(eto 3,l1ommand - su m8todo Add) +. 2especto a la creaci'n de los par$metros, podemos o#servar ,ue es mu- fle9i#le, -a ,ue como vemos en este e(emplo, cada uno de ellos se crea de un modo distinto, especificando el nom#re, tipo de dato - valor.
3i empleamos un o#(eto !le #1ommand, la sinta9is de la sentencia 3;0 cam#ia, -a ,ue los par$metros de#eremos indicarlos como hac&amos en A ! cl$sico, utili/ando el car$cter MPO. Veamos un e(emplo en el 1'digo fuente KA<.
En el caso de ,ue necesitemos e(ecutar un procedimiento almacenado, de#emos indicarlo mediante las propiedades 1ommandT-pe - 1ommandTe9t del o#(eto 1ommand ,ue estemos utili/ando. En la primera esta#lecemos el tipo de comando )procedimiento almacenado+ seleccionando el valor de la enumeraci'n asociada a la propiedad> - en la segunda asignamos una cadena con el nom#re del procedimiento almacenado. El 1'digo fuente KA? muestra un e(emplo, en el ,ue podemos compro#ar ,ue hemos utili/ado un constructor de 3,l1ommand sin par$metros, por lo ,ue el o#(eto 1onnection lo asignamos despu8s mediante la propiedad 1onnection
5ara o#tener el resultado de una funci'n del lengua(e 3;0, por e(emplo 1ount) +, emplearemos el m8todo E9ecute3calar) + del o#(eto 1ommand. En el 1'digo fuente KAK, la e(ecuci'n de este m8todo nos devuelve el n7mero de filas de una ta#la de la #ase de datos, ,ue mostramos en un mensa(e.
un con(unto de registros, no de#emos confundir este m8todo con el m8todo "oveNe9t)+ de A !, -a ,ue en este caso no nos movemos al siguiente registro, sino al siguiente con(unto de registros. $ead* +. espla/a el cursor actual al siguiente registro permitiendo o#tener los valores del mismo a trav8s del o#(eto ata2eader. Este m8todo devolver$ True si e9isten m$s registros dentro del o#(eto ata2eader, False si hemos llegado al final del con(unto de registros. 0a posici'n por defecto del o#(eto ata2eader en el momento inicial es antes del primer registro, por lo tanto para recorrer un o#(eto ata2eader de#emos comen/ar con una llamada al m8todo 2ead)+, - as& situarnos en el primer registro. El #ot'n Empleados crea a partir de un comando, un o#(eto ata2eader ,ue recorremos para llenar un 0istBo9 con los valores de una de las columnas de la ta#la ,ue internamente contiene el ata2eader. Veamos este caso en el 1'digo fuente KAA.
1omo tam#i8n hemos indicado anteriormente, un o#(eto 1ommand puede estar #asado en m7ltiples sentencias 3;0, separadas por el car$cter de punto - coma ) > +, ,ue se e(ecuten en lote. Al crear un ata2eader desde un comando de este tipo, podemos recorrer el con(unto de consultas mediante el m8todo Ne9t2esult) + del ata2eader. 4n e(emplo de este tipo lo tenemos al pulsar el #ot'n 1lientesC5roductos del formulario, cu-o fuente vemos a continuaci'n en el 1'digo fuente KAD. !#serve en este caso ,ue conectamos a trav8s de !0E B, por lo ,ue empleamos los o#(etos A ! .NET de esta categor&a.
0a Figura <?H muestra este formulario despu8s de ha#er rellenado los controles 0istBo9 usando o#(etos ata2eader.