You are on page 1of 63

Marco Besteiro y Miguel Rodrguez ADO.

NET
1 /
57
ADO.NET
Introduccin
ADO .NET responde a las siglas de Microsoft ActiveX Data Objects de la plataforma .NET, y
es una mejora evolutiva de la tenolog!a ADO. "ealmente es una evolui#n m$s en las
tenolog!as de aeso a la informai#n.
En este ap!tulo se omparan las tenolog!as ADO y ADO.NET, se desri%en y detallan los
o%jetos m$s importantes de la tenolog!a, el o%jeto DataSet y los proveedores de aeso a
datos. &e profundi'ar$ so%re el o%jeto DataSet desri%iendo los o%jetos DataTable,
DataColumn, et. En uanto a los proveedores de aeso a datos se desri%ir$ el proveedor
para &() &erver y el proveedor para O)E D*.
Requisitos de la plataforma ADO.NET
+ara utili'ar los proveedores de datos de &() &erver .NET y O)E D* .NET se neesita la
instalai#n de la versi#n ,.- o superior de Microsoft Data Access o!"o#e#ts. +ara utili'ar
ADO.NET en las apliaiones se .a de inluir el namespace System.Data.
Desde DAO hasta ADO
/ae varios a0os nai# un A+1 2A""licatio# $rogra!!i#g %#terface3 llamado OD*4 2O"e#
Database o##ectivity3 dise0ado para proporionar aeso a un amplio rango de or!genes de
datos. 5n origen de datos onsiste %$siamente en los datos asoiados a un sistema de gesti#n
de %ases de datos, la plataforma en la 6ue este sistema e7iste y la red usada para aeder a
di.a plataforma.
+oo tiempo despu8s aparei# la primera interfa' orientado a o%jetos llamado DAO 2Data
Access Objects3 6ue utili'a%a el motor de %ases de datos 9ET de :irosoft ;utili'ado por :&;
Aess; y 6ue permit!a a los programadores de <isual *asi onetar diretamente a ta%las de
Aess y a otras %ases de datos a trav8s de OD*4. Esta interfa' proporiona%a a los
programadores una forma muy senilla de tra%ajar on la informai#n almaenada en las
diferentes %ases de datos. Es entones uando apareen los o%jetos Workspace, Database y el
famoso Recordset 6ue los desarrolladores utili'a%an para rear apliaiones liente;servidor.
DAO era muy efiiente para %ases de datos en loal, o pe6ue0os desarrollos, pero para
apliaiones distri%uidas las prestaiones disminu!an onforme se aumenta%a el n=mero de
usuarios o la omplejidad de las apliaiones.
+or este motivo, aparei# posteriormente otra tenolog!a llamada "DO 2Re!ote Data Objects3
6ue es una interfa' de aeso a datos orientada a o%jetos para OD*4. Tam%i8n es f$il de usar
omo DAO, pero es limitado ya 6ue no funiona muy %ien on el 9et o 1&A:, y s#lo puede
aeder a %ases de datos relaionales a trav8s de drivers OD*4 e7istentes. +ero por otro lado,
permite a los desarrolladores aeder a los proedimientos almaenados y a onsultas m$s
omplejas. Adem$s es mu.o m$s efia' para apliaiones omplejas y on m=ltiples aesos
simult$neos. )os o%jetos m$s utili'ados en esta tenolog!a son Enviroment, Connection y
Resultset.
, /
57
Marco Besteiro y Miguel Rodrguez ADO.NET
Durante un tiempo onviv!an am%as tenolog!as> DAO para apliaiones senillas o loales y
"DO para apliaiones distri%uidas. 5no de los pro%lemas 6ue ten!a la tenolog!a "DO es 6ue
el lenguaje &() on el 6ue se aede a la informai#n de%e de ser el 6ue entienda el sistema
de gesti#n de %ases de datos orrespondiente. +or ejemplo, si se desarrolla ontra &() &erver,
se de%e utili'ar sentenias T;&() ;lenguaje &() propio para &() &erver; y si se programa
ontra Orale se de%e utili'ar sentenias +)/&() ;lenguaje &() propio para Orale;, y
aun6ue T;&() y +)/&() se %asan en &() est$ndar, tienen pe6ue0as diferenias 6ue pueden
.aer 6ue una apliai#n liente;servidor 6ue utilie "DO no funione en otro sistema de
gesti#n de %ases de datos.
4on DAO no e7ist!a este pro%lema y de%ido a este .e.o, a otras irunstanias y so%re todo a
la aparii#n de 4O:, el est$ndar OD*4 evoluion# a O)E D*. O)E D* es un onjunto de
interfaes %asadas en 4O: 6ue e7ponen los datos desde una gran variedad de or!genes de
datos. +osteriormente surgi# la tenolog!a ADO 2ActiveX Data Objects3 6ue se apoya en O)E
D* y 6ue es una interfa' 6ue reoge lo mejor de las dos tenolog!as anteriores, inorporando
adem$s otras mejoras.
)os o%jetos m$s importantes de la tenolog!a ADO son el o%jeto RecordSet, el o%jeto
Command y el o%jeto
Connection.
Connection
Errors
Error
Command
Parameters
Parameter
Recordset
Fields
Field
?igura ,@.1. Diagrama de O%jetos de ADO
ADO.NET frente a ADO
En esta sei#n se desri%en am%as tenolog!as .aiendo .inapi8 en las diferenias
e7istentes.
ADO
)a tenolog!a ADO es una apa 4O: so%re O)E D* de tal manera 6ue las apliaiones 6ue
utilien esta tenolog!a de aeso a datos invoan a los o%jetos de ADO sin tener 6ue onoer
en a%soluto el est$ndar O)E D*. Es una tenolog!a 6ue se utili'a de manera senilla desde
<isual *asi o desde A&+, pero no est$ pensada para <isual 4AA y otros lenguajes.
Cliente ADO
(Visual Basic, ASP,etc.)
ADO
Recordset
ODBC
OLE DB
Base de Datos
?igura ,@.,. Ar6uitetura ADO.
El o%jeto lave dentro de ADO es el Recordset 6ue tiene omo prinipales ventajas su
potenia y senille'. 4on este o%jeto se pueden utili'ar ursores de liente y ursores de
servidor. +or otro lado, aun6ue puede tra%ajar desonetado de la fuente de datos, no est$
pensado para tra%ajar de ese modo, on lo ual se onsiguen implementaiones menos
efiaes de lo 6ue a%!a esperar. ADO est$ pensado para tra%ajar en apliaiones tipo liente;
servidor en los 6ue el Recordset est$ onetado a una fuente de datos y no para
ar6uiteturas on varias apas en las 6ue las prestaiones del Recordset disminuyen.
ADO.NET
)a tenolog!a ADO.NET ;en la versi#n %eta 1 se llama%a ADOA; es un modelo de proveedor
m$s senillo 6ue el par O)ED* / ADO y se integra perfetamente on B:). ADO.NET es la
evolui#n de ADO en la nueva plataforma .NET. Tiene la misma filosof!a pero se .a
modifiado el modelo.
)as prinipales arater!stias de ADO.NET son>
C Tra%aja desonetado del origen de datos 6ue se utilie.
C Tiene una fuerte integrai#n on B:) y A&+ .NET.
C El uso de ADO.NET es independiente del lenguaje de programai#n 6ue se utilie.
+or otra parte se .a demostrado 6ue los niveles de trasferenia de informai#n on ADO.NET
6ue utili'a B:), son tan %uenos omo los niveles 6ue alan'a ADO utili'ando 4O:.
Aplicacin .!E"
#inForms
#e$Forms
#e$ Ser%ices
ADO.!E"
DataSet
DataReader
&ana'ed Pro%iders
S(L Ser%er .... OLE DB
Base de Datos
?igura ,@.D. Ar6uitetura de ADO.NET
)a tenolog!a ADO .NET esta %asada en un nuevo modelo de omponentes en la 6ue las
lases de aeso a datos y las lases ontenedores forman parte del maro de tra%ajo de .NET.
&o%re todo ADO.NET est$ pensado para EinteroperarF on otros omponentes, sistemas, et.
graias al uso de B:) y a soportar est$ndares omo /TT+, B:) o &OA+.
El modelo de ADO.NET est$ dividido en dos grupos>
C )os "roveedores de datos o Ma#aged Data $roviders.
C )os co#te#edores de datos, 6ue aun6ue est$n vinulados a los or!genes de datos, son
independientes de ellos.
En la siguiente ta%la se omparan am%as tenolog!as on m$s detalle.
Caracterstica ADO ADO.NET
"epresentai#n de
datos residente en
memoria.
5tili'a el o%jeto RecordSet,
uyo aspeto es omo una
simple ta%la.
5tili'a el o%jeto DataSet, 6ue
puede ontener una o m$s ta%las
representadas por los o%jetos
DataTable.
"elaiones entre
varias ta%las.
"e6uiere la uni#n de varias
ta%las para mostrar finalmente
una simple ta%la respuesta
&oporta el o%jeto
DataRelation para asoiar filas
en un o%jeto DataTable on
filas de otro o%jeto DataTable.
"eorrido de los )a navegai#n por las filas 5tili'a una forma no seuenial
Marco Besteiro y Miguel Rodrguez ADO.NET
datos. del RecordSet se reali'a de
forma seuenial.
de navegai#n para aeder a
las filas de una ta%la. 5tili'a las
relaiones para navegar desde
filas de una ta%la a las
orrespondientes filas de otra
ta%la.
Aeso desonetado El o%jeto RecordSet posee
esta arater!stia pero el uso
.a%itual es mediante aesos
onetados, representados por
el o%jeto Connection. )a
omuniai#n on la %ase de
datos se reali'a mediante
llamadas al proveedor de
datos O)E D*.
&e omunia on la %ase de
datos mediante llamadas
est$ndares al o%jeto
DataAdapter, el ual se
omunia on el proveedor de
datos O)E D*, o diretamente
a &() &erver.
4ursores 5tili'a tanto ursores de
servidor omo ursores del
lado liente.
4omo la ar6uitetura es
desonetada los ursores no
son aplia%les.
E+rograma%ilidadF 5tili'a el o%jeto Connection
para trasmitir los omandos
6ue tratan la estrutura de
datos 6ue su%yae de una
fuente de datos
5sa B:). )os datos se
desri%en a s! mismos por6ue
los nom%res de las eti6uetas del
#digo orresponden a
pro%lemas del Emundo realF
soluionados por el #digo. )as
estruturas de datos omo
ta%las, filas y olumnas no
apareen .aiendo 6ue el
#digo sea m$s f$il de leer y
esri%ir.
4ompartir datos
desonetados entre
apas y
omponentes.
5tili'a 4O: marshalling
para trasmitir un Recordset
desonetado. &oporta
solamente tipos de datos
definidos por el est$ndar
4O:. "e6uiere onversiones
de tipo 6ue neesitan reursos
del sistema.
Trasmite un DataSet mediante
B:) y este formato no tiene
restriiones en los tipos de
datos y no se re6uiere
onversiones de tipo.
Trasmitir datos a
trav8s de ?ireGalls.
+ro%lem$tio, por6ue los
fireGalls suelen estar
onfigurados para prevenir
petiiones a nivel de sistema,
omo por ejemplo 4O:
marshalling.
&oportado, por6ue los o%jetos
DataSet de ADO.NET utili'an
B:) 6ue puede pasar a trav8s
de un ?ireGall.
Esala%ilidad )os %lo6ueos de la %ase de
datos y las one7iones ativas
de la %ase de datos para las
duraiones largas generan un
El aeso desonetado a los
datos de la %ase de datos sin los
%lo6ueos de reteni#n de la %ase
de datos o las one7iones
5/57
- /57
Marco Besteiro y Miguel Rodrguez ADO.NET
pro%lema en aso de reursos
limitados de la %ase de datos
ativas de la %ase de datos por
per!odos muy largos limita el
pro%lema de los reursos
limitados de la %ase de datos
En resumen> el pro%lema no est$ en elegir entre ADO.NET y ADO. El pro%lema radia en la
elei#n de .NET omo plataforma de desarrollo. &i es as!, entones ADO.NET es la elei#n
orreta.
Namespaces
ADO .NET se %asa en los siguientes espaios de nom%res de aesos a datos>
C System.Data, 6ue proporiona las lases de aeso a datos generales.
C System.Data.Common, 6ue ontiene las lases ompartidas por los proveedores de datos.
C System.Data.OleDb, 6ue almaena las lases del proveedor de datos O)E D*.
C System.Data.SlClient, 6ue e7pone las lases del proveedor de datos para &() &erver.
Que es un ana!ed "ro#ider$%
El Ma#aged $rovider o .NET Ma#aged Data $rovider o simplemente .NET Data $rovider es
el proveedor de datos de la plataforma .NET 6ue permite onetar a un origen de datos on
una apliai#n para reuperar y modifiar informai#n. Tam%i8n este proveedor sirve de
puente entre el origen de datos y el o%jeto m$s importante de ADO.NET, el DataSet 6ue se
ver$ m$s adelante.
)os proveedores de datos en la plataforma .NET ofreen una ar6uitetura de aeso a datos
m$s simple, on arater!stias mejoradas y e7ponen diretamente su omportamiento
espe!fio a los onsumidores. Adem$s tienen un onjunto de interfaes mu.o m$s pe6ue0o
6ue los proveedores O)E D*, y no re6uieren de la tenolog!a 4O:.
)os Ma#aged $roviders aeden al o%jeto DataSet a trav8s de la implementai#n del
interfae !DataAdapter 2ver figura ,@.@3. +or otro lado aeden al origen de datos de forma
onetada a trav8s de o%jetos Connection, Command o "arameter, y proporionan a su ve'
aeso a datos en forma desonetada. )os resultados o%tenidos del origen de datos, pueden
ser proesados diretamente a trav8s del o%jeto DataReader orrespondiente, o depositados
en un o%jeto DataSet para su posterior uso.
Modelo Comn
ADO.NET presenta un modelo om=n para los o%jetos .NET Data $rovider de tal forma 6ue
se pueda odifiar independientemente del proveedor de datos .NET elegido.
.!E" Frame)or*
Aplicacin .!E"
DataSet
Pro%eedor .!E"
+DataReader
+DataAdapter
+DBCommand
Or,'en de Datos
AP+ de acceso a Datos de $a-o !i%el
Base de Datos
?igura ,@.@. Ar6uitetura de los E#anaged "rovidersF
)as interfaes generales, 6ue independientemente del proveedor, se pueden utili'ar on los
proveedores de datos en la plataforma .NET son>
!D$Connection
"epresenta la one7i#n en una =nia sesi#n on un origen de datos determinado
!D$Transaction
"epresenta una transai#n en loal.
!D$Command
"epresenta un omando 6ue se ejeuta uando est$ onetado a un origen de datos.
!Data"arameter
+ermite implementar un par$metro en un omando.
!DataReader
)ee un onjunto de datos de solo letura y EforGard;onlyF de un origen de datos
!DataAdapter * &e enarga de rellenar y de resolver los onflitos del Data&et on el origen de
datos.
!D$DataAdapter
&uministra los m8todos de ejeui#n t!pios para operar on %ases de datos 2insert,
update, selet y delete3
& E# cual'uier caso s(lo el %DataAda"ter es #ecesario.
El siguiente ejemplo tra%aja utili'ando el mismo #digo on am%os proveedores> &() &erver
.NET Data $rovider y O)E D* .NET Data $rovider, es deir, funiona independientemente
de 6ue el o%jeto Connection 2Ob%Cnn3 represente una one7i#n a un &() &erver .NET
Data $rovider o a un O)E D* .NET Data $rovider.
!DbCommand ob%Cmd & ob%Cnn.CreateCommand'()
ob%Cmd.CommandTe*t & +SE,ECT - .RO# Employees+)
!DataReader ob%DR & ob%Cmd.E*ecuteReader'()
/hile ob%DR.Read'(
Console.Write,ine'+0123t042+5 ob%DR.6etString'1(5 ob%DR.6etString'4(()
.NET Data Providers
ADO.NET puede aeder a la informai#n de la %ase de datos solamente a trav8s de los
serviios de los !a#aged "roviders. &e reomienda utili'ar los !a#aged "roviders nativos
siempre 6ue se pueda. ADO.NET uenta on los siguientes proveedores para los diferentes
or!genes de datos>
Ma#aged $rovider para &() &erver 7.H y &() &erver ,HHH
Ma#aged $rovider para proveedores O)E D*
+ara utili'ar los proveedores de aeso a datos de .NET de%e utili'arse el namespace
orrespondiente>
System.Data.SlClient para &() &erver 7.H o &() &erver ,HHH
System.Data.OleDb para proveedores O)E
D*
.!E" Frame)or*
.!E" Frame)or*
Aplicacin .!E"
Aplicacin .!E"
DataSet
DataSet
Pro%eedor .!E"
Pro%eedor .!E"
S.lDataReader
OleD$DataReader
S.lDataAdapter
S.lCommand OleD$DataAdapter OleD$Command
Or,'en de Datos
Or,'en de Datos
AP+ +nterno de S(L Ser%er
OLE DB Pro%ider para el ori'en de datos
S(L Ser%er
Base de Datos
?igura ,@.5. Ma#aged $roviders para &() &erver y para O)E D*
SQL Server .NET Data Provider
Este proveedor de aeso a datos utili'a su propio protoolo para omuniarse on &()
&erver. Aede a los datos sin neesidad de a0adir una apa O)E D* o una apa OD*4.
&e reomienda utili'ar este proveedor tanto para apliaiones liente;servidor omo para
apliaiones on varias apas frente a &() &erver 7.H o superior o frente a :&DE 2Microsoft
Data E#gi#e3. Aun6ue se puede usar el proveedor de datos O)E D* .NET para &() &erver
para aeder al origen de datos, no se reomienda su utili'ai#n ya 6ue el proveedor &()
&erver .NET utili'a el A+1 interno de &() &erver, .aiendo mu.o m$s efia' al proveedor.
+ara el aso de versiones inferiores a la 7.H es neesario utili'ar el proveedor de datos O)E
D* .NET 6ue re6uiere la instalai#n del :DA4 ,.- o posterior.
OLE DB .NET Data Provider
El O)E D* .NET Data +rovider utili'a el O)E D* nativo a trav8s de 4O: para aeder a los
datos soportando transaiones manuales y autom$tias.
+ara utili'ar el proveedor de datos O)E D* .NET es neesario utili'ar tam%i8n el proveedor
O)E D* 2,.- o superior3. )os siguientes proveedores son ompati%les on ADO.NET.
Driver Proveedor
&()O)ED* :irosoft O)E D* +rovider para &() &erver.
:&DAO"A :irosoft O)E D* +rovider para Orale.
:irosoft.9et.O)ED*.@.H O)E D* +rovider para :irosoft 9et.
El proveedor de datos O)E D* .NET no soporta O)E D* ,.5 on lo 6ue no funionar$n los
proveedores siguientes> :irosoft O)E D* +rovider para E7.ange y el :irosoft O)E D*
+rovider para 1nternet +u%lis.ing. Tampoo funiona on el proveedor de datos O)E D* para
OD*4 2:&DA&()3.
&e reomienda este proveedor para apliaiones de varias apas 6ue utilien Orale o &()
&erver -.5 o inferior. +ara apliaiones liente;servidor es m$s onveniente la utili'ai#n de
:irosoft Aess omo origen de datos pero para apliaiones de varias apas :irosoft no
reomienda utili'ar :irosoft Aess.
&os componentes de ADO.NET
)os omponentes de ADO.NET .an sido dise0ados para aeder y manipular datos. /ay dos
omponentes prinipales en ADO.NET 6ue son DataSet y los proveedores de datos .NET
6ue a su ve' inluyen los o%jetos Connection, Command, DataReader y DataAdapter. En
este apartado se desri%ir$ detalladamente ada uno de estos o%jetos.
La clase Connection
Es la lase enargada de esta%leer la one7i#n on el origen de datos y tiene soporte
autom$tio para "ooli#g de one7iones. Dependiendo del origen de datos 6ue se utilie se
de%er$ utili'ar OleDbConnection o SlConnection. &e entiende por "ool de one7iones el
onjunto de one7iones Ea.eadasF en el servidor.
Esta lase implementa la interfae !DbConnection. )a adena de one7i#n al origen de
datos se o%tiene por medio de la propiedad ConnectionString, el estado de la one7i#n por
medio de la propiedad State, para la %ase de datos se utili'a Database y para determinar el
tiempo m$7imo de one7i#n la propiedad ConnectionTimeout.
)os m8todos m$s importantes de esta lase son>
Open
4uando se llama al m8todo Open, se a%re un anal f!sio
on el origen de datos
Close
4ierra la 4one7i#n, pero 8sta no se destruye failitando
el "ooli#g de one7iones. El onsumo en memoria es
%ajo.
$eginTransaction
4omien'a la transai#n
ChangeDatabase
4am%ia de %ase de datos
CreateCommand
4rea un o%jeto 4ommand
)a siguiente ta%la desri%e los estados en los 6ue se puede enontrar la one7i#n.
Open
)a one7i#n est$ a%ierta y funionando
$roken
5na one7i#n previa .a dejado de funionar. De%e ser
errada y rea%ierta.
Closed
Est$ errada.
Connecting
4onet$ndose, la one7i#n est$ siendo a%ierta.
E*ecuting
Ejeutando un omando
.etching
"eogiendo la informai#n del origen de datos.
El proveedor s#lo puede am%iar la adena de one7i#n uando est$ errada 2Closed3. +or
otro lado, los desarrolladores de%er!an utili'ar el m8todo Close uando .ayan aa%ado de
utili'ar la one7i#n, ya 6ue este m8todo ierra la one7i#n y la devuelve al "ool de
one7iones. &in em%argo el m8todo Dispose ierra la one7i#n y destruye la instania del
o%jeto elimin$ndola del "ool de one7iones.
En funi#n del proveedor de datos de la plataforma .NET 6ue se utilie, se puede elegir entre
los lases Connection siguientes> OleDbConnection y SlConnection.
Clase OleDbConnection
Esta lase representa una one7i#n al proveedor de datos O)E D* .NET. )as propiedades
m$s importantes 6ue utili'a son>
C ConnectionString para espeifiar el origen de datos
C ChangeDatabase para am%iar la %ase de datos para one7iones a%iertas.
C ConnectionTimeout para o%tener el tiempo de espera. +or defeto son 15 segundos.
&i se desea 6ue sea ilimitado .a de asign$rsele el valor ero y s#lo podr$ am%iarse su
valor a trav8s de la propiedad ConnectionString.
C &i el estado de la one7i#n am%ia ;propiedad State; entones se produe el evento
StateChange.
Clase SqlConnection
Esta lase representa una one7i#n a la %ase de datos &() &erver 7.H o superior. )as
propiedades m$s importantes son las siguientes>
C &i se produe una e7epi#n en &() 2SlE*ception3 mientras se ejeuta un omando
onreto, la one7i#n permanee a%ierta en aso de 6ue el nivel de severidad sea
menor 6ue 1I. 4on un nivel de severidad mayor 6ue ,H, la one7i#n se ierra y es
neesario rea%rirla para ontinuar.
C )a propiedad ConnectionString espeifia el origen de datos.
C 5n o%jeto SlConnection lee la informai#n de la one7i#n a trav8s de la %ase de
datos y del origen de datos. No neesita leer informai#n del proveedor omo en el
aso de O)E D* .NET.
C )a propiedad ConnectionTimeout o%tiene el tiempo de espera 6ue por defeto son
15 segundos. &i se desea 6ue sea ilimitado .a de asign$rsele el valor ero y solo podr$
am%iarse su valor a trav8s de la propiedad ConnectionString.
C 4uando se utili'a el m8todo Close si e7isten transaiones pendientes en ese
momento, las des.ae 2Roll$ack3.
Creacin de !na cone"in con #is!al St!dio .NET
En <isual &tudio .NET e7iste la posi%ilidad de reali'ar una one7i#n de forma muy senilla
utili'ando el Explorador de servidores.
?igura ,@.-. E7plorador de one7iones en <isual &tudio .NET
+ara rear una one7i#n, %asta on seleionar on el %ot#n dere.o Agregar conexin de la
figura ,@.-. &e aede a onfigurar la one7i#n dependiendo del proveedor 6ue se utilie. A
ontinuai#n, se reali'an dos ejemplos de one7i#n.
A$ Para el caso de !na cone"in a SQL Server
+ara el aso de una one7i#n a la %ase de datos Nort.Gind en &() &erver se elige el
proveedor para &() &erver, el servidor, la %ase de datos y el usuario junto on la ontrase0a
2?igura ,@.73.
?igura ,@.7. +ropiedades de la one7i#n a &() &erver.
5na ve' rellenados los datos, es posi%le o%servar todos los elementos de la %ase de datos.
?igura ,@.J. 4one7i#n a la %ase de datos Nort.Gind en &() &erver.
5na ve' 6ue la one7i#n est8 reada %asta on seleionarla y arrastrarla .asta el formulario
donde va a ser utili'ada.
B$ Para el caso de !na cone"in a !na base de datos Access.
&e seleiona el proveedor de aeso a datos 9et @.H O)E D* +rovider y se elige la %ase de
datos Neptuno de Aess ,HHH.
?igura ,@.I. +ropiedades de la one7i#n a una %ase de datos de Aess
Despu8s de rear la one7i#n se puede aeder a los diferentes elementos de la %ase de datos,
6ue en este aso se dividen en ta%las, vistas y proedimientos almaenados. )as vistas en
Aess son tam%i8n denominadas Eonsultas de selei#nF, y los proedimientos
almaenados, %ien pueden ser onsultas on par$metros, o onsultas de uni#n, o onsultas de
referenias ru'adas o onsultas de ai#n ;!nsert, 7pdate, Create o Delete; disponi%les
en Aess.
?igura ,@.1H. Elementos de la %ase de datos Neptuno
Transacciones en ADO.NET
+ara empe'ar una transai#n en ADO .NET se llama al m8todo $eginTransaction 6ue
aepta el par$metro !solation,evel 2nivel de aislamiento3 y/o el nom%re, y devuelve un
o%jeto transai#n de la lase OleDbTransaction o SlTransaction dependiendo del
proveedor 6ue se utilie.
El o%jeto SlTransaction soporta savepoints o puntos de almaenamiento de la
transai#n 6ue permiten des.aerla 2Roll$ack3 m$s tarde. +ara almaenar un savepoint
se utili'a el m8todo Save. Esta funionalidad es e6uivalente a la delarai#n E&A<E
T"AN&A4T1ONF 6ue se reali'a en T;&().
&i se 6uiere des.aer una transai#n ya almaenada, .a de utili'arse el m8todo Rollback
6ue puede llevar omo par$metro el nom%re del punto de almaenamiento previamente
guardado. En aso de 6uerer aeptar la transai#n se utili'ar$ el m8todo Commit.
A ontinuai#n se reali'a un ejemplo on &() &erver>
String strCone*ion & 8SER9ER&'local() uid&sa) p/d&sa) database&:orth/ind;)
SlConnection Ob%Cnn & ne/ SlConnection'strCone*ion()
Ob%Cnn.Open'()
<< Comien=a la transacci>n
SlTransaction Ob%Tran & Ob%Cnn.$eginTransaction'()
try
0
2
<< E%ecuci>n de comandos
<< Se e%ecuta el Commit de la Transacci>n
Ob%Tran.Commit'()
catch 'E*ception e*(
0
<< ,a transacci>n ha ?allado
Ob%Tran.Rollback'()
2
Ob%Cnn.Close'()
A ontinuai#n se reali'a un ejemplo on O)E D*.
String strCone*ion & '+"rovider & #icroso?t.@et.O,ED$.A.1)Data Source &
:eptuno.#D$+)
OleDbConnection Ob%CnnO,E& ne/ OleDbConnection'strCone*ion()
Ob%Cnn.Open'()
<< Comien=a la transacci>n
OleDbTransaction Ob%Tran & Ob%CnnO,E.$eginTransaction'()
try
0
<< E%ecuci>n de comandos
<< Se e%ecuta el Commit de la Transacci>n
Ob%Tran.Commit'()
2
catch 'E*ception e*(
0
<< ,a transacci>n ha ?allado
Ob%Tran.Rollback'()
2
Ob%CnnO,E.Close'()
La clase Command
5n o%jeto de la lase Command al igual 6ue un o%jeto de la lase Connection pertenee
al proveedor de aeso a datos de la plataforma .NET, as! 6ue a la .ora de odifiar se puede
utili'ar la interfa' !Command om=n a todos los proveedores 2todos ellos la implementan3, o
las lases espe!fias de alguno de los proveedores 6ue proporiona la plataforma .NET.
5n o%jeto Command %$siamente formula una petii#n y se la env!a al origen de datos. &i
esa petii#n devuelve datos, el o%jeto Command se enarga de empa6uetarlos y devolverlos
omo un o%jeto DataReader, un valor esalar o omo los par$metros de salida utili'ados
en el propio omando.
E7isten dos propiedades muy importantes de la lase Command>
C CommandTe*t. "epresenta una adena o te7to uya sinta7is es omprendida por el
proveedor de aeso a datos .NET 6ue se utilie.
C CommandType. Esta propiedad india la forma en la 6ue la propiedad CommandTe*t va
a ser interpretada y su valor por defeto es CommandType.Te*t. )os valores 6ue puede
tomar esta propiedad son>
o CommandType.Te*t. 1ndia 6ue la propiedad CommandTe*t es un te7to plano.
+or ejemplo>
String strSB, & ;SE,ECT - .RO# Employees;)
SlCommand Ob%Cmd & ne/ SlCommand'strSB,5 Ob%Cnn()
<< ,a lCnea siguiente no es necesaria porue Te*t es el
<< valor por de?ecto
Ob%Cmd.CommandType & CommandType.Te*t)
o CommandType.Stored"rocedure. "epresenta 6ue la propiedad CommandTe*t
es el nom%re de un proedimiento almaenado.
+or ejemplo>
String strS" & ;CustOrdersDetail;)
SlCommand Ob%Cmd & ne/ SlCommand'strS"5 Ob%Cnn()
Ob%Cmd.ComamndType & CommandType.Stored"rocedure)
o CommandType.TableDirect. 4on esta propiedad se india 6ue el
CommandTe*t es el nom%re de una ta%la del origen de datos. Esta opi#n no
est$ soportada en el &() &erver .NET Data "rovider.
+or ejemplo>
String strTabla & ;Employees;)
OleDbCommand Ob%Cmd & ne/ OleDbCommand'strTabla5 Ob%Cnn()
Ob%Cmd.CommandType & CommandType.TableDirect)
4uando se est$ utili'ando un o%jeto Command se neesita 6ue un o%jeto Connection .aya
sido a%ierto. &iempre .ay una transai#n asoiada a la one7i#n. &i se EreseteaF la one7i#n
entones el o%jeto transai#n devuelve null. En prinipio, se puede am%iar la one7i#n sin
pro%lema alguno para onetar on otro usuario o para onetar a otra fuente de datos, pero
.ay 6ue tener en uenta 6ue la transai#n 6ue su%yae sea ompati%le on la one7i#n.
)os par$metros del o%jeto Command perteneen a una olei#n llamada
OleDb"arameterCollection o Sl"arameterCollection dependiendo del proveedor
seleionado. Estas oleiones est$n ompuestas por o%jetos OleDb"arameter o
Sl"arameter respetivamente.
+ara rear un nuevo par$metro e7isten dos posi%ilidades, o %ien utili'ar el operador :e/ de
la lase "arameter, o %ien tra%ajar on el m8todo Create"arameter de la lase Command.
+ara ejeutar un omando se neesita 6ue .aya una one7i#n v$lida a%ierta y dependiendo del
omportamiento 6ue se desee dar al o%jeto Command se utili'ar$ uno de los siguientes
m8todos>
C E*ecute:onBuery> No devuelve un onjunto de registros sino 6ue devuelve el n=mero
de filas afetadas por la ai#n.
C E*ecuteReader> Devuelve un onjunto de registros de s#lo letura y EforGard;onlyF.
No se informa del n=mero de filas afetadas.
C E*ecuteScalar> Devuelve s#lo el valor de la elda 2H,H3 del onjunto de registros.
El omportamiento 6ue puede tener un o%jeto Command est$ reogido en la propiedad
Command$ehavior 6ue desri%e los resultados y la forma en la ual la onsulta de%er!a
afetar al origen de datos. &e puede utili'ar el m8todo E*ecuteReader para alterar el
omportamiento del o%jeto Command mediante las siguientes opiones>
C CloseConnection. 4ierra la one7i#n uando se ierra el o%jeto DataReader
C Dey!n?o. :uestra informai#n de la lave primaria o "ri!ary )ey y de las olumnas
sin reali'ar %lo6ueo de las filas.
C SchemaOnly. :uestra informai#n solo de las olumnas y no %lo6uea las filas.
C SeuentialAccess. El ontenido de la olumna puede leerse de golpe utili'ando el
m8todo 6et$ytes del o%jeto DataReader.
C SingleResult. Devuelve un =nio onjunto de datos, en aso de e7istir varios, s#lo
devolver$ el primero de ellos.
C SingleRo/. &e utili'a uando se espera 6ue la onsulta devuelva una =nia fila. )os
proveedores de datos est$n optimi'ados on esta opi#n para ejeutar este tipo de
onsultas.
4omo ya se .a desrito anteriormente la lase Command pertenee al proveedor de aeso a
datos .NET, de tal forma 6ue e7isten las lases OleDbCommand y SlCommand para el
proveedor O)E D* .NET y &() &erver .NET respetivamente.
Clase OleDbCommand
Esta lase representa una delarai#n O)E D* para ejeutar ontra un origen de datos O)E
D*. Esta delarai#n puede ser un omando &(), el nom%re de un proedimiento almaenado
onreto, o %ien ual6uier te7to 6ue entienda el proveedor O)E D*.
Tiene diferentes onstrutores>
a3 Command Te*t. Ejeuta una sentenia omprensi%le por el proveedor.
%3 Command Te*t E OleDbConnection. Ejeuta una sentenia %ajo una one7i#n
su%yaente.
3 Command Te*t E OleDbConnection E OleDbTransaction. Ejeuta una sentenia
en una transai#n %ajo una one7i#n su%yaente.
Antes de ejeutar el omando se asegura 6ue la one7i#n est$ a%ierta.
E7isten otras propiedades omo CommandType y CommandTimeout 6ue por defeto vale DH
segundos.
Al ejeutar el omando OleDbCommand se pueden utili'ar los siguientes m8todos>
C E*ecuteReader, 6ue devuelve un o%jeto OleDbDataReader despu8s de ejeutar una
sentenia &() de selei#n &E)E4T.
+or ejemplo>
String strSB, & ;SE,ECT - .RO# Employees;)
OleDbCommand Ob%Cmd & ne/ OleDbCommand'strSB,5 Ob%CnnO,E()
OleDbDataReader Ob%Reader & Ob%Cmd.E*ecuteReader'()
/hile 'Ob%Reader.Read'((
0
Console.Write'Ob%ReaderF1G.ToString'(()
2
C E*ecute:onBuery, se utili'a para ejeutar onsultas de ai#n mediante l$usulas
omo !:SERT, 7"DATE, DE,ETE, CREATE, SET prinipalmente. Esta sentenia devuelve
un entero indiando el n=mero de filas afetadas por la ai#n. )#giamente modifia
el valor de la propiedad RecordA??ected.
+or ejemplo>
String strSB, & ;7"DATE Employees SET lastname&H!sabelH WIERE
Employee!D&J;)
OleDbCommand Ob%Cmd & ne/ OleDbCommand'strSB,5 Ob%CnnO,E()
Ob%Cmd.E*ecute:onBuery'()
C E*ecuteScalar. Devuelve el =nio valor de la primera fila y primera olumna del
resultado o%tenido de la ejeui#n. &e utili'a mu.o para o%tener valores alulados en
proedimientos almaenados.
+or ejemplo>
String strSB, & ;SE,ECT CO7:T'-( .RO# Employees;)
OleDbCommand Ob%Cmd & ne/ OleDbCommand'strSB,5 Ob%CnnO,E()
Ob%ect Ob%Au* & Ob%Cmd.E*ecuteScalar'()
Clase SqlCommand
"epresenta una sentenia T;&() o un proedimiento almaenado y tiene los siguientes
onstrutores>
a3 Command Te*t. Ejeuta una sentenia omprensi%le por &() &erver
%3 Command Te*t E SlConnection. Ejeuta la sentenia %ajo la one7i#n on &()
&erver su%yaente.
3 Command Te*t E SlConnection E SlTransaction. Ejeuta una sentenia en
una transai#n %ajo una one7i#n &() &erver su%yaente.
Al ejeutar el omando SlCommand se pueden utili'ar los siguientes m8todos
C E*ecuteReader, 6ue devuelve un o%jeto SlDataReader despu8s de ejeutar una
sentenia &() de selei#n &E)E4T. &e pueden ejeutar proedimientos almaenados
del sistema de &() &erver.
+or ejemplo>
String strSB, & ;SE,ECT - .RO# Employees;)
SlCommand Ob%Cmd & ne/ SlCommand'strSB,5 Ob%Cnn()
SlDataReader Ob%Reader & Ob%Cmd.E*ecuteReader'()
/hile 'Ob%Reader.Read'((
0
Console.Write'Ob%ReaderF1G.ToString'(()
2
C E*ecute:onBuery, se utili'a para ejeutar onsultas de ai#n mediante l$usulas
omo !:SERT, 7"DATE, DE,ETE, CREATE, SET prinipalmente. Esta sentenia devuelve
un entero indiando el n=mero de filas afetadas por la ai#n. )#giamente modifia
el valor de la propiedad RecordA??ected.
+or ejemplo>
String strSB, & ;7"DATE Employees SET lastname&HAlvaroH WIERE
Employee!D&J;)
SlCommand Ob%Cmd & ne/ SlCommand'strSB,5 Ob%Cnn()
Ob%Cmd.E*ecute:onBuery'()
C E*ecuteScalar. Devuelve el =nio valor de la primera fila y primera olumna del
resultado o%tenido de la ejeui#n. &e usa mu.o para o%tener valores alulados o
antidades totales.
+or ejemplo>
String strSB,&;SE,ECT CO7:T'-( .RO# Employees;)
SlCommand Ob%Cmd&ne/ SlCommand'strSB,5 Ob%Cnn()
Ob%ect Ob%Au* & Ob%Cmd.E*ecuteScalar'()
C E*ecuteKmlReader. Devuelve un o%jeto KmlReader despu8s de ejeutar el omando
&E)E4T 6ue e7plota las arater!stias B:) de &() &erver ,HHH.
String strSB,&;SE,ECT - .RO# Employees .OR K#, A7TO;)
SlCommand Ob%Cmd&ne/ SlCommand'strSB,5 Ob%Cnn()
KmlReader Ob%KR & cmd.E*ecuteKmlReader'()
/hile 'Ob%KR.Read'((
0
Console.Write,ine'Ob%KR.ReadOuterKml'(()
2
Creacin de !n ob%eto Command con #is!al St!dio .NET
A ontinuai#n se reali'ar$n dos ejemplos. El primero utili'a la lase SlCommand en &()
&erver y en el segundo se tra%aja on la lase OleDbCommand para Aess.
A$ Creacin de !n ob%eto SqlCommand &ara SQL Server
&up#nga 6ue se dispone de un formulario al 6ue se .a a0adido un o%jeto SlConnection
llamado slConnection4. El primer paso es a0adir un o%jeto slCommand al formulario
2pesta0a Data del cuadro de herramientas3 .
?igura ,@.11. 4uadro de .erramientas de la pesta0a Data
A ontinuai#n, en la ventana de propiedades, en la propiedad Connection se .a de
seleionar el o%jeto slConnection deseado ;en este aso slConnection4;. El =ltimo
paso es indiar la e7presi#n &() v$lida. &i por ejemplo se desea 6ue el omando utilie
una onsulta so%re los pedidos de la %ase de datos Nort.Gind, se puede utili'ar la propiedad
CommandTe*t 6ue dispone de un asistente para el dise0o de onsultas si milar al 6ue
proporiona &() &erver
?igura ,@.1,. Asignai#n de la one7i#n al ontrol slCommand
.
?igura ,@.1D. Kenerador de onsultas de <isual &tudio .NET
y una ve' onstruida la onsulta, la sentenia &() generada es asignada a la propiedad
CommandTe*t del omponente
SlCommand.
B$ Creacin de !n ob%eto OleDbCommand &ara Access
&e parte de 6ue e7iste una one7i#n a la %ase de datos Aess llamada Neptuno.
+osteriormente se arrastra un o%jeto OleDbCommand del uadro de .erramientas al
formulario, y se asigna la one7i#n al omando mediante la propiedad Connection. &i se
aede a la propiedad CommandTe*t se esta%lee la e7presi#n del omando por medio del
generador de onsultas, omo se india en la figura ,@.1D.
?igura ,@.1@. +ropiedades del o%jeto OleDbCommand
Llamadas a Procedimientos Almacenados en ADO.NET
+ara ejeutar un proedimiento almaenado se de%e utili'ar el tipo de omando para
proedimientos almaenados y elegir el m8todo de ejeui#n 6ue m$s se adeue al resultado
esperado. &i el proedimiento almaenado 6ue se va a ejeutar posee par$metros, se de%en
rear antes de ejeutarlo indiando si son de entrada o de salida.
El siguiente proedimiento almaenado de la %ase Nort.Lind es utili'ado en varios ejemplos.
&u nom%re es CustOrdersDetail y re6uiere un par$metro 6ue orresponde on el
identifiador o n=mero de pedido.
CREATE "ROCED7RE CustOrdersDetail LOrder!D int
AS
SE,ECT "roduct:ame5 7nit"rice&RO7:D'Od.7nit"rice5 J(5 Buantity5
Discount&CO:9ERT'int5 Discount - 411(5
E*tended"rice&RO7:D'CO:9ERT'money5Buantity-'4MDiscount(-Od.7nit"rice(5 J(
.RO# "roducts "5 FOrder DetailsG Od
WIERE Od."roduct!D & "."roduct!D and Od.Order!D & LOrder!D
A ontinuai#n se presenta un ejemplo de llamada al proedimiento almaenado
CustOrderDetail en &() &erver.
+or ejemplo* &up#nga 6ue e7iste una one7i#n a%ierta a la %ase de datos Nort.Gind en &()
&erver llamada Ob%Cnn.
<< :otaN Debe estar declarado el namespace System.Data.SlClient)
SlCommand ob%Cmd & ne/ SlCommand'8CustOrdersDetail;5 Ob%Cnn()
ob%Cmd.CommandType & CommandType.Stored"rocedure)
Sl"arameter ob%"ar &ne/ Sl"arameter'8LOrder!D;5 SlDbType.!nt()
ob%"ar.Direction & "arameterDirection.!nput)
ob%"ar.9alue & 4A)
ob%Cmd."arameters.Add'ob%"ar()
SlDataReader dr & ob%Cmd.E*ecuteReader'Command$ehavior.CloseConnection()
Nota> El proveedor de datos &() &erver .NET no soporta el ar$ter interrogai#n para
o%tener la informai#n de los par$metros, pero s! lo .ae el proveedor O)E D* .NET.
La clase Data'eader
5n o%jeto de la lase DataReader es muy similar a un Recordset de ADO pero 6ue
=niamente soporta las siguientes arater!stias>
C ReadOnly. &olo letura.
C .or/ard Only. &olo lee .aia delante.
Estas dos arater!stias .aen 6ue un o%jeto de la lase DataReader sea muy r$pido ya 6ue
no tiene implementadas las arater!stias de edii#n, eliminai#n, inseri#n, navegai#n de
registros .aia atr$s, et. 6ue redundan en un peor rendimiento del o%jeto. Es una efiiente
alternativa para or!genes de datos desonetados, pero es menos esala%le 6ue la lase
Dataset, ya 6ue no permite ser .eredado por otra lase.
)a lase DataReader no tiene onstrutor y es neesario llamar al m8todo E*ecuteReader
del o%jeto Command orrespondiente para rear un o%jeto DataReader. De%e ser errado
e7pl!itamente.
El m8todo Read se utili'a para leer los registros. 4uando se rea un o%jeto DataReader
siempre se a%re y se posiiona en el primer registro, on lo 6ue no .ay 6ue .aer una llamada
e7pliita a ning=n m8todo del tipo #ove.irst. El m8todo Read lee siempre la siguiente fila.
DataReader Ob%DR & Ob%C#D.E*ecuteReader'()
Ob%DR.Read'()
+ara aeder a los valores de las olumnas del o%jeto DataReader se puede aeder tanto
por n=mero omo por nom%re.
+or ejemplo>
DataReader Ob%DR & Ob%C#D.E*ecuteReader'()
Ob%DR.Read'()
Console.Write'Ob%DR.6et!ntOJ'1(.ToString'(()
<< o Console.Write'Ob%DRF8Employee!D;G.ToString'(()
Otras propiedades interesantes de la lase DataReader
son>
C )a propiedad RecordsA??ected toma un valor determinado uando se reali'an
aiones omo inseriones, atuali'aiones o eliminaiones de registros. En aso de
reali'ar onsultas de selei#n, esta propiedad no reoge ning=n valor .asta 6ue no se
.an le!do todos los registros, y se .aya errado el o%jeto DataReader orrespondiente.
C )a propiedad :e*tResult sirve para aeder al siguiente onjunto de resultados.
C .ieldCount devuelve el n=mero de olumnas o ampos del onjunto de registros
pero no aporta informai#n aera del n=mero de filas devueltas.
E7isten multitud de m8todos espe!fios de letura omo 6etString, 6et$oolean, 6et!ntOJ,
et. Otros m8todos interesantes del o%jeto DataReader son 6et.ieldType y 6et9alues
6ue devuelven una matri' de o%jetos desri%iendo los valores de las filas.
En la versi#n atual del frameGorM .NET se desri%en dos lases 6ue implementan la interfae
!DataReader, una para el est$ndar O)E D* y otra para &() &erver llamadas
OleDbDataReader y SlDataReader respetivamente.
OleDbData'eader
Es la lase 6ue se utili'a en aso de un aeso de datos est$ndar y es v$lida para ual6uier
%ase de datos, inluido &() &erver. Aun6ue l#giamente para &() &erver se utili'ar$ la lase
SlDataReader.
4uando se leen datos y la one7i#n 6ue su%yae est$ oupada no se puede .aer otras
operaiones so%re el o%jeto OleDbDataReader e7epto errarlo. N una ve' 6ue el o%jeto
OleDbDataReader est$ errado s#lo se pueden utili'ar dos de sus propiedades> !sClosed23 y
RecordsA??ected
SqlData'eader
)a lase SlDataReader de%e ser utili'ada uando se aede a una %ase de datos en &()
&erver. Esta lase es muy similar a la lase OleDbDataReader, ya 6ue tiene las mismas
arater!stias. E7isten multitud de m8todos espe!fios de este proveedor del tipo 6etSlK**
6ue devuelven datos de distintos tipos de datos de &(). +or ejemplo> 6etSl$inary,
6etSlString, et.
(n e%em&lo con #is!al St!dio .NET)
En este ejemplo se representa, en una lista de un formulario, los empleados de la %ase de datos
de Nort.Gind en &() &erver. &e rea un proyeto on un formulario, posteriormente se
agrega una eti6ueta 2label43 y un uadro de lista 2list$o*43 desde el uadro de
.erramientas. ?inalmente se esri%e en el evento ,oad del formulario el siguiente #digo, uya
finalidad es mostrar #mo tra%aja un o%jeto DataReader para rellenar una lista on datos de
una %ase de datos.
String strConn & +SER9ER&localhost) 7!D&sa) DATA$ASE&:orth/ind)+)
string strCmd & +SE,ECT Employee!D5 ,ast:ame5 .irst:ame .RO# Employees+)
string str,ista)
<< Rellena el DataReader
SlDataReader Ob%DR)
SlConnection Ob%Cnn & ne/ SlConnection'strConn()
SlCommand Ob%Cmd & ne/ SlCommand'strCmd5 Ob%Cnn()
Ob%Cnn.Open'()
Ob%DR & Ob%Cmd.E*ecuteReader'()
label4.Te*t & +,ista de Empleados+)
<< Recogiendo por los registros.
/hile'Ob%DR.Read'((
0
str,ista & Ob%DR.6et!ntOJ'1(.ToString'()
str,ista E& + M + E Ob%DR.6etString'4()
str,ista E& + + E Ob%DR.6etString'J()
list$o*4.!tems.Add'str,ista()
2
Ob%Cnn.Close'()
El resultado se representa en la siguiente figura>
?igura ,@.15. "esultado del ejemplo on DataReader
La clase DataAda&ter
)a lase DataAdapter se enarga de las operaiones entre la apa de datos y la apa
intermedia, donde los datos son transferidos. &e puede deir 6ue sirve omo puente entre un
o%jeto DataSet y un origen de datos asoiado para reuperar y guardar datos.
*$siamente permite rellenar 2.ill3 el o%jeto DataSet para 6ue sus datos oinidan on los
del origen de datos y permite atuali'ar 27pdate3 el origen de datos para 6ue sus datos
oinidan on los del DataSet.
DataAda&ter
SelectCommand
+nsertCommand
Base de Datos
/pdateCommand
DeleteCommand
"a$le&appin's
DataSet
?igura ,@.1-. Diagrama del o%jeto DataAdapter
)os onstrutores de la lase son>
C DataAdapter'Command selectCommand(. &e utili'a un omando de selei#n
2l$usula &E)E4T3 omo par$metro.
C DataAdapter'String selectCommandTe*t5 String
selectConnectionString(. &e utili'a una sentenia &() de selei#n on una
adena de one7i#n omo par$metros.
C DataAdapter'String selectCommandTe*t5 Connection selectConnection(.
&e utili'an los par$metros sentenia &() de selei#n y un o%jeto de tipo
one7i#n.
En la interfae !DataAdapter se delaran los siguientes m8todos 2toda lase 6ue
implemente esta interfae est$ o%ligada a implementarlos3.
C .ill'DataSet ds(. "ellena un o%jeto de la lase Dataset.
C .illSchema'DataSet ds5 SchemaType st(. "ellena un es6uema on un
DataSet indiando el tipo de es6uema a rellenar.
C 7pdate'DataSet ds(. Atuali'a el DataSet orrespondiente.
C 6et.ill"arameters'(. "eoge el onjunto de par$metros uando se ejeuta una
onsulta de selei#n.
)a olei#n Table#appings mantiene el seguimiento del enlae entre un o%jeto DataTable
del DataSet y un origen de
datos.
5n o%jeto de la lase DataAdapter soporta batc+,u"dates, es deir 6ue puede reali'ar varias
atuali'aiones en un solo proeso. 4uando una apliai#n llama al m8todo 7pdate, la lase
e7amina la propiedad Ro/State para ada fila en el DataSet y ejeuta la lausula
!:SERT, 7"DATE o DE,ETE re6uerida.
)as prinipales propiedades de la lase DataAdapter son SelectCommand, !nsertCommand,
7pdateCommand y DeleteCommand, 6ue es donde residen las sentenias &() para onsultar,
insertar, atuali'ar y eliminar registros respetivamente.
Todos los proveedores de datos de la plataforma .NET soportan una lase 6ue .ereda de la
lase DbDataAdapter 6ue .ereda a su ve' de la lase DataAdapter, la ual implementa la
interfae !DataAdapter. En mu.os asos es sufiiente on una lase 6ue implemente el
interfae !DataAdapter.
)as lases m$s representativas soportadas por los proveedores son OleDbDataAdapter y
SlDataAdapter 6ue son muy
similares.
(tili*acin del com&onente DataAda&ter en #is!al St!dio .NET.
En el momento en 6ue se agrega el omponente DataAdapter desde el uadro de
.erramientas .asta el formulario, aparee autom$tiamente un asistente para rear y
onfigurar el omponente DataAdapter.
A$ Caso de !n ob%eto SqlDataAda&ter
+ara este ejemplo se va a utili'ar un omponente SlDataAdapter 6ue se onfigurar$ a
partir del proedimiento almaenado CustOrdersDetail de la %ase datos Nort.Lind en
&() &erver.
?igura ,@.17. +ropiedades del o%jeto SlDataAdapter
5na ve' generado el omponente slDataAdapter4, se pueden modifiar las propiedades as!
omo utili'ar los tres asistentes o .erramientas siguientes.
-. Asiste#te "ara co#figurar el ada"tador de datos. Este asistente es el mismo 6ue aparee
uando se arrastra el omponente DataAdapter en el formulario. +or ejemplo, si se
seleiona el proedimiento almaenado CustOrdersDetail de la %ase datos Nort.Lind en
&() &erver, se puede rellenar los datos para la selei#n, para agregar nuevos registros, para
atuali'ar y para %orrar registros.
?igura ,@.1J. Asistente para la onfigurai#n del adaptador de datos 2DataAdapter3
/. Asiste#te "ara ge#erar el co#ju#to de datos. Es el asistente 6ue permite generar un o%jeto
DataSet.
?igura ,@.1I. Kenerai#n del onjunto de datos 2DataSet3
3) Asiste#te "ara visualizar los datos, 6ue se utili'a para disponer de una vista previa de los
datos 6ue reupera el o%jeto DataAdapter del origen de datos.
?igura ,@.,H. Asistente para la vista previa de datos
En este ejemplo en partiular omo el proedimiento almaenado rei%e un par$metro, para
o%tener el onjunto de datos es neesario rellenarlo. En la figura ,@.,H se .a elegido el #digo
de pedido u Order!D on el valor 1HJ5H.
B$ Caso de !n ob%eto OleDbDataAda&ter
En este aso se utili'a un omponente OleDbDataAdapter 6ue se onfigurar$ a partir de una
onsulta de selei#n so%re la ta%la Empleados de la %ase datos Neptuno en Aess.
?igura ,@.,1. +ropiedades del o%jeto OleDbDataAdapter.
&e puede o%servar 6ue tiene las tres mismas .erramientas o asistentes 6ue el o%jeto
SlDataAdapter.
-. Asiste#te "ara co#figurar el ada"tador de datos. Este asistente es el mismo 6ue en el aso
anterior salvo 6ue no se pueden rear proedimientos almaenados.
En di.o asistente se pueden onfigurar unas opiones avan'adas para el aso de instruiones
&(), 6ue es el aso del ejemplo. Di.as opiones avan'adas permiten onfigurar la
generai#n o no de las instruiones !nsert, 7pdate y Delete. Tam%i8n permiten onfigurar
si la onurrenia ser$ optimista y por =ltimo si se ejeuta una sentenia &E)E4T despu8s de
las instruiones !nsert y 7pdate para reuperar los diferentes valores de la %ase de datos.
?igura ,@.,,. Asistente para la onfigurai#n del DataAdapter
/. Asiste#te "ara ge#erar el co#ju#to de datos. Es el asistente 6ue permite generar un o%jeto
DataSet.
?igura ,@.,D. Kenerai#n del onjunto de datos
0. Asiste#te "ara visualizar los datos, 6ue se utili'a para disponer de una vista previa de los
datos 6ue reupera el o%jeto DataAdapter del origen de datos.
?igura ,@.,@. <ista previa del o%jeto OleDbDataAdapter.
La clase DataSet
)a lase DataSet es la lase prinipal de la ar6uitetura ADO.NET. 5n o%jeto de esta lase es
una representai#n en memoria de los datos en forma relaional. Es un a.8 de datos
e7tra!dos de un ontenedor de datos gen8rio. El o%jeto DataSet se rellena on
DataAdapters, on datos loales, o %ien on B:).
?igura ,@.,5. Ar6uitetura del o%jeto DataSet
)as oleiones m$s importantes son la olei#n DataTables 6ue ontiene las ta%las donde
reside la informai#n y la olei#n DataRelations 6ue ontiene las distintas relaiones
entre las ta%las del DataSet. &e puede ontener informai#n espe!fia del usuario a trav8s de
la olei#n E*tended"roperties.
Tanto los datos, omo el es6uema o am%os se pueden representar en formato B:), y para
aeder a la informai#n se utili'an los m8todos 6etKml, ReadKml y WriteKml.
5na arater!stia importante de la lase DataSet es 6ue permite aeptar o re.a'ar todos
los am%ios reali'ados en las ta%las, ya sean eliminaiones, atuali'aiones o reaiones
de nuevos registros. Todos estos am%ios se pueden aeptar en un solo paso siendo muy =til
uando se neesiten proesar distintos %lo6ues de datos durante un tiempo en memoria. A
vees puede ser interesante mantener durante toda una sesi#n un DataSet en memoria
onsiguiendo reali'ar un solo aeso a la %ase de datos para almaenarlo y otro al final de la
sesi#n para almaenar los am%ios.
Creacin de !n DataSet mediante controles en #is!al St!dio .NET
+ara rear y rellenar un DataSet on <isual &tudio .NET se de%e reali'ar los siguientes pasos>
1. &e rea un formulario y se a0ade un ontrol de tipo Connection 2OleDbConnection
o SlConnection3 arrastr$ndolo desde el uadro de .erramientas. &e onfigura la
one7i#n para aeder al origen de datos deseado, tal y omo se .a desrito
anteriormente.
,. &e a0ade al formulario un ontrol DataAdapter 2OleDbDataAdapter o
SlDataAdapter3 y se onfigura omo tam%i8n se .a desrito.
D. &e seleiona el ontrol DataAdapter y se aede a la .erramienta o asistente para
generar el onjunto de datos o DataSet.
?igura ,@.,-. Asistente de generai#n del DataSet
5na ve' 6ue el o%jeto DataSet .a sido a0adido al formulario, se puede aeder a las
propiedades del onjunto de datos o a ver el es6uema del DataSet.
DataTable
DataTable
DataCol!mn
DataCol!mn
DataCol!mn
DataCol!mn
DataCol!mn
?igura ,@.,7. +ropiedades del DataSet o onjunto de
datos.
&i se desea agregar m$s ta%las al DataSet se pueden rear m$s o%jetos DataAdapter y
agregarlos al DataSet e7istente. )a ventaja de a0adir las diferentes ta%las desde ontroles
DataAdapter es 6ue se agregan tanto los ampos on sus tipos de datos, nom%res, et, y
adem$s se a0aden las restriiones de%idas a la lave primaria de las ta%las en el origen de
datos.
La clase DataTable
)a lase DataTable representa una ta%la en memoria y es donde reside la informai#n de
los datos. 5n o%jeto de la lase DataTable se puede utili'ar on o sin un o%jeto DataSet,
pero si se 6uiere rellenar, entones de%e asoiarse al DataSet. 4on un o%jeto DataTable al
igual 6ue on un o%jeto DataSet se tiene la posi%ilidad de re.a'ar o aeptar todos los
am%ios en una sola ve'. +or otra parte las ta%las tienen relaiones, restriiones, laves
primarias, filas y olumnas 6ue son o%jetos 6ue se ven a ontinuai#n.
El m8todo .ill del DataAdapter rellena un DataSet on s#lo las olumnas de la ta%la y
los registros. )a informai#n aera de las restriiones de la ta%la, si se desean, de%en ser
a0adidas al DataSet utili'ando la olei#n Constraints del o%jeto DataTable.
&e reomienda 6ue el o%jeto DataSet posea la informai#n e7istente so%re restriiones en
el origen de datos, y para onseguirlo se puede reurrir o %ien a llamar al m8todo
.illSchema del o%jeto DataAdapter, o %ien a esta%leer la propiedad
#issingSchemaAction del o%jeto DataAdapter a AddWithDey antes de llamar al m8todo
.ill. A0adir la informai#n del es6uema antes de rellenar el o%jeto DataSet asegura 6ue
la informai#n de la lave primaria se inluye en el o%jeto DataTable.
DataSet
DataTable
Constraints
'elations
Data'o+
,ML Sc-ema
?igura ,@.,J. Estrutura prinipal de los o%jetos DataSet y
DataTable
&a clase Data'olumn
El onjunto de olumnas de un o%jeto DataTable orresponde a una olei#n de o%jetos
DataColumn. 5n o%jeto DataColumn tiene omo propiedades importantes la propiedad
Column:ame 6ue india el nom%re de la olumna, y la propiedad DataType 6ue india el
tipo de olumna. Adem$s tiene la propiedad Allo/D$:ull para sa%er si la %ase de datos
permite
nulos para esa olumna, la propiedad Auto!ncrement 6ue deteta si la olumna es o no
autonum8ria, la propiedad De?ault9alue 6ue esta%lee o lee el valor por defeto de la
olumna y la propiedad E*presi>n 6ue esta%lee o reoge la e7presi#n utili'ada para filtrar
filas o la e7presi#n de un ampo alulado entre olumnas o la e7presi#n de un ampo suma,
promedio, et. )as propiedades ReadOnly y 7niue se utili'an para esta%leer o reoger si
la olumna es de solo letura y ada valor el =nio para todas las filas.
&a clase DataRo(
4omo en el aso de la lase DataColumn, el onjunto de filas de un o%jeto DataTable
orresponde a una olei#n de o%jetos DataRo/. )a propiedad !temFnG o !temFnombreG
lee o esta%lee el valor de las olumnas. Dos de los m8todos m$s importantes del o%jeto
DataRo/ son el m8todo !s:ull'n( o !s:ull'nombre( 6ue india si una olumna es nula.
E)emplo de Data*et+ DataTa,le+ Data'olumn - DataRo(
El siguiente #digo muestra #mo utili'ar los o%jetos DataSet, DataTable, DataColum y
DataRo/.
DataSet ob%DS & ne/ DataSet'()
DataTable ob%Tabla & ne/ DataTable'+Tabla,ocal+()
<< "reparando las columnas
DataColumn ob%Col & ne/ DataColumn'+Ciudad+()
ob%Col.DataType & Type.6etType'+System.String+()
ob%Tabla.Columns.Add'ob%Col()
DataColumn ob%ColJ & ne/ DataColumn'+"ais+()
ob%ColJ.DataType & Type.6etType'+System.String+()
ob%Tabla.Columns.Add'ob%ColJ()
<< Se aPade el DataTable al Dataset 'Antes de Rellenar(
ob%DS.Tables.Add'ob%Tabla()
<< Se aPaden unas ?ilas...
DataRo/ ob%.ila & ob%Tabla.:e/Ro/'()
ob%.ilaF+Ciudad+G & +$ilbao+)
ob%.ilaF+"ais+G & +EspaPa+)
ob%Tabla.Ro/s.Add'ob%.ila()
<< Se vincula al Data6rid
data6rid4.Data#ember & + Tabla,ocal +)
data6rid4.DataSource & ob%DS)
'estricciones de datos
+ara esta%leer reglas o restriiones on los o%jetos en memoria, ADO.NET presenta las
siguientes restriiones, 6ue pueden ser de varios tipos>
.oreignDeyConstraint. ?uer'a un vinulo entre dos DataTables del DataSet
7niueConstraint. &e asegura 6ue la olumna 6ue tenga esta restrii#n no pueda tener filas
on el mismo dato en esa olumna.
ADO .NET proporiona adem$s la propiedad "rimaryDey del o%jeto DataTable 6ue
o%tiene o esta%lee un n=mero de olumnas omo laves primarias de la ta%la en memoria,
pero este onjunto de olumnas 6ue forman la lave primaria en el o%jeto DataTable no
tiene por 6ue oinidir on las olumnas 6ue forman la lave primaria en la %ase de datos. El
uso de esta lave ayuda a prevenir errores omunes uando se atuali'a la ta%la en memoria y
a vees el uso de esta lave primaria en memoria a.orra la reoniliai#n de datos posterior
on la %ase de datos.
E%em&lo de !na a&licacin Maestro.Detalle con #is!al St!dio .NET
&e pretende reali'ar una apliai#n .NET 6ue onste de un formulario donde apare'an los
pedidos en un Data6rid y sus l!neas de pedido en otro, y 6ue ada ve' 6ue se seleione
un pedido onreto, apare'an sus orrespondientes l!neas en el otro Data6rid. Adem$s no se
utili'ar$n los ontroles de one7i#n, adaptai#n y ontenedor de datos inluidos en <isual
&tudio .NET.
A$ Para !na base de datos en SQL Server
+ara reali'ar este ejemplo se utili'an las ta%las Orders y Order Details de la %ase de
datos
Nort.Gind en &() &erver.
?igura ,@.,I. Ta%las Orders y Order Details de la %ase de datos
Nort.Gind
&e insertan dos ontroles Datagrid en el formulario> el ontrol datagrid4 se situar$ en
la parte i'6uierda y ontendr$ la informai#n relativa a los pedidos 2Orders3 y el ontrol
datagridJ estar$ en la parte dere.a y ontendr$ las l!neas orrespondientes al pedido
seleionado 2Order Details3.
?igura ,@.DH. ?ormulario :aestro;Detalle
4omo se va a tra%ajar on la %ase de datos en &() &erver se a0adir$ el namespace
orrespondiente>
using System.Data.SlClient)
A ontinuai#n se define el o%jeto Dataset on el se va a tra%ajar y 6ue se llama ods"edidos.
Este o%jeto se define omo p=%lio en la lase .orm4.
public DataSet ods"edidos)
5na ve' definido el o%jeto Dataset donde va a residir la informai#n de los pedidos y de
las l!neas de pedido, se proede a argar el o%jeto Dataset en el evento 1oad del
formulario .orm4.
private void .orm4Q,oad'ob%ect sender5 System.EventArgs e(
0
2
)o primero 6ue .ay 6ue .aer es definir la one7i#n on el servido. Despu8s se inorpora la
informai#n de la ta%la pedidos 2Orders3 al DataSet y posteriormente se a0ade al DataSet
la informai#n de la ta%la l!neas de pedido.
5na ve' 6ue se tiene el DataSet on la informai#n, se de%en esta%leer las relaiones entre
las ta%las 6ue lo forman. &e puede o%nservar 6ue las ta%las del DataSet no tienen por6u8
oinidir on las ta%las del origen de datos, ni en n=mero de ampos, ni en las laves, ni en los
nom%res de las ta%las, ampos, et.
N por =ltimo se vinulan las ta%las a los Data6rids
orrespondientes.
private void .orm4Q,oad'ob%ect sender5 System.EventArgs e(
0
string
sCone*ion&+database&north/ind)uid&sa)p/d&sa)server&localhost)+)
DataSet ods"edidos & ne/ DataSet'()
<< Se rellena el DataSet con la tabla "edidos 'Orders(
string sSB,"edidos & +SE,ECT - .RO# Orders+)
SlDataAdapter Ob%DA & ne/ SlDataAdapter'sSB,"edidos5sCone*ion()
Ob%DA..ill'ods"edidos5+Orders+()
<<Se rellena el DataSet con las lineas del "edido 'Order Details(
string sSB,,ineas & +SE,ECT - .RO# FOrder DetailsG+)
Ob%DA.SelectCommand.CommandTe*t & sSB,,ineas)
Ob%DA..ill'ods"edidos5+OrderDetails+()
<<Se establece la relaci>n entre las entidades en el DataSet
DataColumn Ob%Col"edidos &
ods"edidos.TablesF+Orders+G.ColumnsF+Order!D+G)
DataColumn Ob%Col,ineas &
ods"edidos.TablesF+OrderDetails+G.ColumnsF+Order!D+G)
DataRelation Ob%Relacion & ne/
DataRelation'+rel"edidos+5Ob%Col"edidos5Ob%Col,ineas()
ods"edidos.Relations.Add'Ob%Relacion()
<<Se vincula a los Data6rids la in?ormaci>n
data6rid4.DataSource & ods"edidos)
data6rid4.Data#ember & +Orders+)
data6ridJ.DataSource & ods"edidos)
data6ridJ.Data#ember & +Orders.rel"edidos+)
2
N el resultado se presenta en la siguiente figura>
?igura ,@.D1. ?ormulario :aestro;Detalle de +edidos y l!neas de pedidos
Este ejemplo tam%i8n se puede reali'ar utili'ando los ontroles de one7i#n, adaptai#n y
ontenedor de datos inluidos en el <isual &tudio .NET.
B$ Para !na base de datos Access
&up#nga 6ue se desea reali'ar un formulario :aestro;Detalle de la %ase de datos Neptuno en
Aess, pero esta ve' se utili'ar$n los ontroles de <isual &tudio.
En primer lugar se agrega la one7i#n OleDbConnection4 a la %ase de datos Neptuno y
despu8s se despliega la one7i#n en el e7plorador de one7iones y se arrastran al formulario
las ta%las "roductos y "roveedores. Entones se o%serva omo se rean dos o%jetos
DataAdapter.
&e elige uno ual6uiera de los dos DataAdapter y se genera el onjunto de datos o DataSet
desde las propiedades del mismo. En la ventana del asistente de la generai#n del DataSet se
elige tam%i8n el otro DataAdapter.
?igura ,@.D, Asistente para generar un DataSet a partir de dos o%jetos
DataAdapter.
5na ve' 6ue el DataSet .a sido generado, se proede a rear la relai#n entre las ta%las
generadas en el DataSet ;"roductos y "roveedores; 6ue posteriormente rellenar$n los
Data6rid del formulario. +ara rear la relai#n se seleiona el ampo IDProveedor de
la ta%la "roveedores y se aede al men= onte7tual mediante el %ot#n dere.o para rear
una relai#n 6ue relaiona un proveedor on varios produtos.
?igura ,@.DD. "elai#n de las ta%las "roveedores y "roductos en el
DataSet.
&e aede a la propiedad DataSource del Data6rid4 6ue es donde se 6uiere e7poner los
proveedores, y se seleiona el dataSet44 omo valor y en la propiedad Data#ember se
seleiona "roveedores.
?igura ,@.D@. +ropiedad DataSource del
Data6rid.
En el aso del Data6ridJ se rellena la propiedad DataSource on dataSet44 y la
propiedad Data#ember on "roveedores."roveedores"roductos, 6ue de esta forma se
mara el vinulo entre los dos ontroles Data6rid. &i se rellena la propiedad Data#ember
on el valor "roductos, en el Data6ridJ apareer!an todos los produtos, y no los del
proveedor seleionado en el Data6rid4.
A.ora solo falta rellenar el DataSet, 6ue se reali'ar$ al argar el formulario, mediante los dos
o%jetos OleDbDataAdapter, uno para argar la ta%la proveedores y otro para argar la ta%la
produtos.
private void .orm4Q,oad'ob%ect sender5 System.EventArgs e(
0
oleDbDataAdapter4..ill'dataSet44()
oleDbDataAdapterJ..ill'dataSet44()
2
?igura ,@.D5. ?ormulario :aestro;Detalle de "roveedores y
"roductos.
Este ejemplo se .a reali'ado utili'ando los ontroles, .erramientas y asistentes 6ue
proporiona <isual &tudio .NET, pero tam%i8n se podr!a .a%er reali'ado de forma similar al
ejemplo anterior ;en &() &erver;, 6ue no utili'a ning=n ontrol de datos .NET, ni tampoo
asistentes.
La clase DataSet / ,ML
)a lase DataSet es la =nia lase de la plataforma .NET 6ue puede reoger datos de una
fuente en B:) y enviarlos en el mismo formato. +ara reali'ar estas aiones un o%jeto
DataSet utili'a el m8todo 6etKml 6ue devuelve una representai#n B:) del DataSet
pero no inluye la informai#n del es6uema 2para ello se de%er$ utili'ar el
m8todo 6etKmlSchema(.
)os m8todos del DataSet para leer son ReadKml 6ue lee tanto los datos omo el es6uema, y
el m8todo ReadKmlSchema 6ue solo se utili'a parta leer la informai#n del es6uema.
En el siguiente ejemplo se rellena un o%jeto DataSet desde un fi.ero
B:).
String str.ichero & 8CN3K#,3e%emplo.*ml;
System.!O.StreamReader Ob%SR & ne/ System.!O.StreamReader'str.ichero()
DataSet Ob%DS & ne/ DataSet'()
Ob%DS.ReadKml'Ob%SR()
Ob%SR.Close'()
El m8todo WriteKml se utili'a para enviar el ontenido del DataSeta un o%jeto
StreamWriter en formato B:) O es m$s r$pido 6ue esri%ir lo 6ue devuelve el m8todo
6etKml y se puede utili'ar independientemente de tener la informai#n del es6uema. En
aso de 6uerer esri%ir la informai#n del es6uema se utili'ar$ el m8todo WriteKmlSchema.
El o%jeto DataSet tiene las propiedades :amespace 6ue esta%lee u o%tiene el namespace
usado uando se lee o esri%e el doumento B:), y "re?i* 6ue reoge o esta%lee el prefijo
B:) 6ue sirve de alias del namespace del DataSet.
+ara rear un DataSet adem$s de .aerlo on el m8todo .ill del DataAdapter, se
puede partir de #digo B:)AB&D. Tam%i8n e7isten otros o%jetos aparte del DataSet
leer informai#n en B:) omo son KmlReader, Te*tReader o StreamReader.
System.Kml.KmlReader)
System.!O.StreamReader)
System.!O.Te*tReader
En <isual &tudio .NET se puede ver el es6uema del o%jeto DataSet, utili'ando la opi#n
orrespondiente.
?igura ,@.D-. "epresentai#n en B:) del DataSet de
pedidos.
La clase Data#ie+
5n o%jeto de la lase Data9ie/ representa una vista ordenada y/o filtrada de un o%jeto
DataTable y se utili'a mu.o uando se desea vinular datos on los Web.orms
2?ormularios Le%3 o los Win.orms 2?ormularios LindoGs3.
5n o%jeto Data9ie/ ontiene o%jetos DataRo/9ie/ 6ue tiene omo propiedades
importantes
!tem2!ndie3 para aeder a la fila deseada y Count para reoger el n=mero total de
filas.
)as prinipales aiones 6ue se pueden reali'ar on un o%jeto Data9ie/ son la de filtrar y
ordenar. +ara filtrar es posi%le utili'ar las propiedades Ro/.ilter para o%tener o esta%leer la
e7presi#n para filtrar las filas, o la propiedad Ro/State.ilter 6ue reoge el estado del
filtro. +ara ordenar se utili'an las propiedades Sort, 6ue es la e7presi#n de adena 6ue se
utili'a para ordenar, y ApplyDe?aultSort 6ue india si se utili'a la ordenai#n por defeto.
A ontinuai#n se reali'a un ejemplo de filtro>
private void .iltrar.ilas'(
0
int i)
<< Se crea un DataTable con una columna. DataTable
Ob%Tabla & ne/ DataTable'+Tabla+() DataColumn
Ob%Columna & ne/ DataColumn'+Columna+()
Ob%Tabla.Columns.Add'Ob%Columna()
<< Se aPaden 41 ?ilas.
DataRo/ Ob%.ila)
?or'i & 1)i R 41 )iEE(
0
Ob%.ila & Ob%Tabla.:e/Ro/'()
Ob%.ilaF+Columna+G & +item + E i)
Ob%Tabla.Ro/s.Add'Ob%.ila()
2
Ob%Tabla.AcceptChanges'()
<< Crear un Data9ie/ con la Tabla.
Data9ie/ Ob%9ista & ne/ Data9ie/'Ob%Tabla()
<< Cambiar el valor de una ?ila
Ob%Tabla.Ro/sF4GF+Columna+G & +Iello+)
<< APadir una ?ila
Ob%.ila & Ob%Tabla.:e/Ro/'()
Ob%.ilaF+Columna+G & +World+)
Ob%Tabla.Ro/s.Add'Ob%.ila()
<< Establece el Ro/State.ilter para ver solo las ?ilas
<< aPadidas y modi?icadas.
Ob%9ista.Ro/State.ilter &
Data9ie/Ro/State.Added S Data9ie/Ro/State.#odi?iedCurrent)
<< #uestra las ?ilas
#ostrar9ista'Ob%9ista5 +ReciTn modi?icada y aPadida+()
<< Establece el ?iltro para mostrar el valor original
<< de las ?ilas modi?icadas
Ob%9ista.Ro/State.ilter&Data9ie/Ro/State.#odi?iedOriginal)
#ostrar9ista'Ob%9ista5+9alor Original+()
<< $orrar tres ?ilas.
Ob%Tabla.Ro/sF4G.Delete'()
Ob%Tabla.Ro/sFJG.Delete'()
Ob%Tabla.Ro/sFOG.Delete'()
<< Establece el Ro/State.ilter para ver solo las ?ilas
<< aPadidas y modi?icadas
Ob%9ista.Ro/State.ilter&Data9ie/Ro/State.Deleted)
#ostrar9ista'Ob%9ista5+Deleted+()
<<Establece el ?iltro para mostrar solo las en curso
Ob%9ista.Ro/State.ilter&Data9ie/Ro/State.CurrentRo/s)
#ostrar9ista'Ob%9ista5+En Curso+()
<< Establece el ?iltro para mostrar solo las ?ilas ue no cambian
Ob%9ista.Ro/State.ilter&Data9ie/Ro/State.7nchanged)
#ostrar9ista'Ob%9ista5+:o cambian+()
<< Establece el ?ilto para mostrar las ?ilas originales.
Ob%9ista.Ro/State.ilter&Data9ie/Ro/State.OriginalRo/s )
#ostrar9ista'Ob%9ista5+.ilas Originales+()
2
private void #ostrar9ista'Data9ie/ dv5string label(
0
Console.Write,ine'+3n+ E label()
?or'int i & 1)i R dv.Count )iEE(
0 Console.Write,ine'dvFiG
F+Columna+G.ToString'(()
2
Adem$s el o%jeto Data9ie/ soporta las operaiones generales de edii#n por medio de las
propiedades Allo/:e/, Allo/Delete y Allo/Edit para esta%leer las operaiones %$sias
y los m8todos Add:e/ y Delete para agregar una fila y eliminarla respetivamente.
)as operaiones de %=s6ueda del o%jeto Data9ie/ vienen reflejadas por el m8todo .ind
6ue devuelve el !ndie de la fila enontrada por los riterios de filtrado.
+or ejemplo>
Data9ie/ Ob%D9)
!nteger i)
Ob%ect valsF4G)
DataTable Ob%Tabla)
Ob%D9 & :e/ Data9ie/'Ob%Tabla()
Ob%D9.Sort & +Customers+)
<< Encontrar el cliente llamado !sabel #artin.
valsF1G& +!sabel+)
valsF4G & +#artin+)
i & Ob%D9..ind'vals()
Console.Write,ine'Ob%D9FiG()
&e puede personali'ar diferentes vistas on un o%jeto DataTable y utili'ar un o%jeto
Data9ie/ para representar una de esas vistas
El control Data#ie+ en #is!al St!dio .NET
+ara rear un ontrol Data9ie/ %asta on arrastrarlo al formulario. 5na ve' asignado al
formulario se esta%lee la propiedad Table donde se seleiona la ta%la del DataSet deseada.
?igura ,@.D7. +ropiedades del ontrol Data9ie/. &elei#n de la Ta%la.
La clase Data'elation
5na relai#n es un vinulo din$mio esta%leido entre una o m$s olumnas del mismo tipo de
dos ta%las y el o%jeto DataRelation representa una relai#n maestro;detalle entre dos ta%las.
5na ve' 6ue se .a esta%leido la relai#n entre dos ta%las ual6uier am%io 6ue infrinja la
relai#n provoar$ una e7epi#n. )as relaiones admiten am%ios en asada desde la ta%la
maestro a la ta%la detalle a0adiendo un o%jeto .oreignDeyConstraint a la olei#n de
restriiones del o%jeto DataTable. A ontinuai#n se muestra un ejemplo en el 6ue se define
una relai#n de atuali'ai#n en asada.
<< Sup>nga ue se tiene un DataSet llamado Ob%DS
<< con las tablas Orders y OrderDetails
DataColumn Ob%Col#aestro & ob%DS.Tables'8Orders;(.Columns'8Order!D;()
DataColumn Ob%ColDetalle & ob%DS.Tables'8OrderDetails;(.Columns'8Order!D;()
.oreignDeyConstraint Ob%.D & ne/ .oreignDeyConstraint'8.DQODQOrder!D;5
Ob%Col#aestro5 Ob%ColDetalle()
<< Se crea la actuali=aci>n en cascada
Ob%.D.7pdateRule & Rule.Cascade)
<< Se aPade a la tabla OrderDetails del DataSet la restricci>n
Ob%DS.Tables'8OrderDetails;(.Constraints.Add'Ob%.D(
A partir de a6u!, estando en una fila de la ta%la maestro es posi%le aeder a las filas de la
ta%la detalle diretamente utili'ando la el m8todo 6etChildRo/s del o%jeto DataRo/, 6ue
devuelve un array de o%jetos DataRo/.
&i se utili'an relaiones se de%e tener en uenta 6ue no son transitivas, de tal forma 6ue si la
ta%la A est$ relaionada on la ta%la *, y por otro lado la ta%la * est$ relaionada on la ta%la
4, no se puede deir 6ue las ta%las A y 4 est8n relaionadas.
Creacin de !na relacin con #is!al St!dio .NET.
+ara rear una relai#n en un DataSet desde el dise0ador de <isual &tudio .NET %asta on
aeder a un DataSet donde e7istan varias ta%las y seleionar la opi#n de agregar
relacin. 5na ve' reali'ada esta ai#n se pueden onfigurar los elementos tanto primario
omo seundario, y las olumnas 6ue van a formar parte de la relai#n. Adem$s se
pueden onfigurar las reglas para atuali'ar o eliminar en asada.
?igura ,@.DJ. Edii#n de una relai#n
)a representai#n de la relai#n se puede o%servar en la siguiente figura.
?igura ,@.DI. "epresentai#n gr$fia del es6uema del DataSet on <isual &tudio
5na ve' 6ue la relai#n .a sido esta%leida se puede o%servar en el ejemplo maestro;detalle
anterior, 6ue al atuali'ar el valor de la olumna Order!D 1H,51 por el valor ,1,
autom$tiamente las filas relaionas de la ta%la Order Details am%ian a ,1, de%ido a la
onfigurai#n en asada, para la atuali'ai#n, esta%leida en la relai#n.
?igura ,@.@H. Atuali'ai#n en asada en el formulario maestro;detalle
Traba%ando con !n ob%eto DataSet
)as vistas on filtro permiten implementar es6uemas del tipo maestro;detalle onsiguiendo
argar en el mismo DataSet las ta%las on la informai#n del maestro y del detalle,
posteriormente se esta%leen dos vistas on filtro una para la ta%la maestra y otra para la ta%la
detalle. 4on la versi#n anterior de ADO esto no era posi%le, y la =nia forma de traer toda la
informai#n era repetir los ampos de la ta%la maestro tantas vees omo detalles tuviese,
mediante una vista, onsiguiendo peores prestaiones 6ue on ADO .NET.
El m8todo Select de la lase DataTable permite o%tener un array o onjunto de filas
6ue oiniden on un riterio espeifiado y %ajo un orden fijado.
4ada DataRo/ tiene una propiedad Ro/State 6ue puede ser e7aminada para determinar
su estado. )os posi%les estados de esta propiedad est$n representados en la siguiente ta%la.
Estado
Descripci>n
7nchanged
No se .an produido am%ios desde la ultima llamada a
AcceptChanges
Added
)a fila .a sido a0adida a la ta%la pero no se .a llamado a
AcceptChanges
#odi?ied
Alg=n elemento de la fila .a sido am%iado
Deleted
)a fila .a sido eliminada de la ta%la utili'ando el m8todo Delete
Detached
)a fila .a sido eliminada pero no se .a llamado a AcceptChanges o la
fila .a sido reada pero no .a sido a0adida a la ta%la
5na de las formas de a0adir nuevas filas a un o%jeto DataTable es rear un o%jeto DataRo/,
rellenarlo y luego agregarlo al o%jeto DataTable.
+or ejemplo>
DataRo/ Ob%.ila & Ob%Tabla.:e/Ro/'(
Ob%.ilaF+D:!+G & 8UUUUUUU;)
Ob%.ilaF+:ombre+G & 8Alvaro;)
Ob%.ilaF+Apellidos+G & 86arcia ,ope=;)
Ob%.ilaF+Email+G & 8agarciaLempresa.es;)
Ob%Tabla.Ro/s.Add'Ob%.ila()
+ara %orrar filas de un o%jeto DataTable %asta seleionar una serie de filas y luego llamar
al m8todo Delete o Remove.
Delete mara la fila omo %orrada pero mantiene el registro original y permite des.aer la
eliminai#n.
Remove %orra f!siamente la fila de la ta%la. Es omo llamar al m8todo Delete y
posteriormente aeptar los am%ios mediante AcceptChanges.
)as aiones de %orrado de filas se reali'an en el o%jeto DataTable 6ue est$ en memoria. A
la .ora de atuali'ar on el origen de datos se de%e tener en uenta 6ue una fila %orrada on
Remove no es peri%ida omo %orrada y por lo tanto no es %orrada del origen de datos. &in
em%argo la fila 6ue es %orrada on el m8todo Delete es %orrada en el origen de datos.
El .e.o de marar una fila omo %orrada 2Delete3 india 6ue la fila ser$ eliminada de la
ta%la despu8s de llamar a AcceptChanges. 4uando se reali'a esta operai#n la propiedad
Ro/State am%ia al estado Deleted. &i se invoa el m8todo Re%ectChanges entones la
propiedad Ro/State volver$ a su estado iniial.
En el aso de 6ue se %orre una fila 6ue justo se .a%!a a0adido a la ta%la y 6ue .a%!a sido
marada omo :e/ utili'ando Delete, Delete funiona omo Remove.
4uando se desea reoniliar las ta%las en memoria on las ta%las en el origen de datos se
utili'a el m8todo 6etChanges para rear un segundo DataSet en loal 6ue ontiene s#lo
los am%ios 6ue se van a .aer 2filas maradas3. +osteriormente se e7amina la propiedad
IasErrors del DataSet para ver si e7isten errores en alguna de las filas de las ta%las del
propio DataSet. &i se produen errores, se de%er$ reoniliar antes de atuali'ar los datos del
DataSet 2memoria3 on el origen de datos. +ara reoger los errores se utili'a el m8todo
6etErrors 6ue devuelve los o%jetos DataRo/ 6ue tienen errores. &i se posi%le reoniliar
los
errores entones se llama al m8todo #erge para volver a inorporar los am%ios del segundo
DataSet al
primero.
+ara atuali'ar el origen de datos y refresar la ta%la se llama al m8todo AcceptChanges y en
aso de 6ue se desee des.aer la atuali'ai#n se llamar$ al m8todo Re%ectChanges.
El m8todo AcceptChanges se puede apliar al o%jeto DataSet, al o%jeto DataTable o al
o%jeto DataRo/, y funiona en asada, es deir, 6ue si se aplia so%re el DataSet, se est$
apliando so%re todas las ta%las del DataSet, y si se aplia so%re el o%jeto DataTable, se est$
apliando so%re todas las filas de esa ta%la.
4uando se llama al m8todo AcceptChanges
C )os o%jetos DataRo/ 6ue est8n todav!a en edii#n se almaenan
C )a propiedad Ro/State de ada fila am%ia adeuadamente.
C )as filas nuevas y modifiadas pasan a ser filas normales y las %orradas 2Deleted3
pasan a eliminadas definitivamente.
4uando se llama al m8todo Re%ectChanges se anelan las filas 6ue esta%an en edii#n, se
eliminan los nuevos registros y las filas modifiadas o %orradas 2Deleted3 pasan a su estado
original.
En uanto a la atuali'ai#n del origen de datos, se reomienda utili'ar omo primera opi#n
omandos &() y omo segunda opi#n la atuali'ai#n tipo Batc+ o masiva 6ue onsiste en
un proeso 6ue e7trae datos del lado liente y los atuali'a en la %ase de datos. Este tipo de
atuali'ai#n 2Batch3 se puede reali'ar on un onjunto de o%jetos DataRo/, on un o%jeto
DataSet o on un o%jeto DataTable. +ara reali'ar la atuali'ai#n tipo Batc+ se .a de
utili'ar el m8todo 7pdate del o%jeto DataAdapter 6ue reali'a una llamada a los omandos
!:SERT, 7"DATE y DE,ETE para ada fila agregada, atuali'ada o %orrada. Es onveniente
utili'ar el m8todo 6etChanges para enviar al origen de datos un DataSet m$s pe6ue0o.
E%em&lo de act!ali*acin en #is!al St!dio .NET
+ara reali'ar este ejemplo se .a de rear un proyeto nuevo en <isual &tudio .NET, on un
formulario y se .a de a0adir una one7i#n a la %ase de datos Nort.Gind en &() &erver. &e
agrega, despu8s, un ontrol DataAdapter al formulario utili'ando una sentenia &() so%re
la ta%la de "edidos>
SE,ECT
Order!D5
Customer!D5
Employee!D5
OrderDate5
ReuiredDate5
ShippedDate5
Ship9ia
.RO# Orders
5na ve' generado on asistente el ontrol DataAdapter, entones se generan
autom$tiamente las propiedades DeleteCommand, !nsertCommand y 7pdateCommand.
+osteriormente on el ontrol DataAdapter se genera el ontrol DataSet, y se agrega un
ontrol Data6rid y un ontrol $utton al formulario. :$s adelante se vinula el ontrol
Data6rid on la ta%la Orders del DataSet y se prepara el evento ,oad del formulario
para 6ue se rellene el o%jeto DataSet 6ue autom$tiamente rellenar$ el 6rid.
private void .orm4Q,oad'ob%ect sender5 System.EventArgs e(
0
slDataAdapter"edidos..ill'dataSet"edidos5+Orders+()
2
+osteriormente se agregan tres filas 2DataRo/3 al formulario.
?igura ,@.@1. Atuali'ai#n tipo Batc+ de tres filas
En este instante la informai#n no est$ en la %ase de datos, est$ en memoria en el DataSet, de
tal manera 6ue si se ierra el formulario la informai#n se pierde y no se atuali'a en la %ase
de datos.
+ara atuali'ar las tres filas en un =nio proeso se puede utili'ar un %ot#n omo el 6ue se .a
definido en este ejemplo.
private void buttonActuali=arQClick'ob%ect sender5 System.EventArgs e(
0
i? 'dataSet"edidos.IasChanges'((
0
try
0
DataSet dataSetCambios & dataSet"edidos.6etChanges'()
slDataAdapter"edidos.7pdate'dataSetCambios5 +Orders+()
dataSet"edidos.AcceptChanges'()
2
catch 'D$ConcurrencyE*ception dbError(
0
<< Resolver el con?licto
#essage$o*.Sho/'+ErrorN+ E dbError.ToString'(()
2
2
2
En este ejemplo, primero se pregunta si se .an reali'ado am%ios, y si esto es as! se utili'a un
segundo DataSet para tratar solo las filas alteradas. )uego se atuali'an en la %ase de datos
di.as filas.

You might also like