Sei sulla pagina 1di 83

20-mayo-2007 Usando LINQ to SQL (1 Parte)

Publicado en LINQ, LINQ to SQL, Scott Guthri a 7:1 !m !or "uanma

#n lo$ %ltimo$ me$e$ he e$crito una $erie de !o$t &ue cubr'an al(una$ de la$ caracter'$tcia$ &ue )an a )enir con *i$ual Studio y +N#, -rame.or/ 01rca$2+ 3&u' ten4i$ lo$ enlace$: Pro!iedade$ autom5tica$, iniciali6adore$ de ob7ecto$ e iniciali6adore$ de collecione$+ 84todo$ de e9ten$i:n+ #9!re$ione$ Lambda+

Sinta9i$ de con$ulta$+ ,i!o$ 3n:nimo$

La$ caracter'$tica$ anteriore$ hacen &ue la con$ulta de dato$ $ea un conce!to de !rimera cla$e+ ;onocemo$ a e$te modelo de !ro(ramaci:n como 0LINQ2 < &ue )iene de +N#, Lan(ua(e Inte(rated Query+ Lo$ de$arrolladore$ !ueden u$ar LINQ con cual&uier =uente de dato$+ Pueden e9!re$ar con$ulta$ e=icientemente en lo$ len(ua7e$ de !ro(ramaci:n &ue eli(an, o!cionalmente tran$=ormar>incru$tar lo$ re$ultado$ de la$ con$ulta$ en el =ormato &ue &uieran, y entonce$ mani!ular =5cilmente lo$ re$ultado$+ Lo$ len(ua7e$ habilitado$ !ara LINQ !ueden a!ortar $e(uridad de ti!o$ y che&ueo en tiem!o de com!ilaci:n el la$ e9!re$ione$ de con$ulta, y de$arrollar herramienta$ &ue a!orten inteli$en$e, debu((in(, y un (ran $o!orte !ara re=actorin( cuando e$criban c:di(o de LINQ+ LINQ $o!orta un modelo de e9ten$ibilidad muy rico &ue =acilita la creaci:n de o!eradore$ e=iciente$ !ara =uente$ de dato$+ La )er$i:n 01rca$2 del +N#, -rame.or/ biene con librer'a$ &ue habilitan LINQ $obre ob7eto$, ?8L y ba$e$ de dato$+ Qu es LINQ to SQL? LINQ to SQL e$ una im!lementaci:n de 1>@8Aob7ect relational ma!!in(, ma!eador de ob7eto$ relacionale$B &ue )iene con la )er$i:n 01rca$2 del +N#, -rame.or/, y

no$ !ermite modelar ba$e$ de dato$ relacionale$ con cla$e$ de +N#,+ Podemo$ con$ultar ba$e$ de dato$ con LINQ, a$' como actuali6ar>aCadir>borrar dato$ de ella$+ Modelando bases de datos con LINQ to SQL: *i$ual Studio 01rca$2 )iene con un di$eCador de LINQ to SQL &ue no$ a!orta una =orma =5cil de modelar y )i$uali6ar una ba$e de dato$ como un modelo de ob7eto de LINQ to SQL+ #l !r:9imo !o$t cubrir5 en m5$ !ro=undidad c:mo u$ar e$te di$eCador A!od4i$ )er 4$te )ideo &ue hice en #nero !ara )erme con$truir un modelo LINQ to SQLB+ D$ando e$e di$eCador LINQ to SQL !uedo crear =5cilmente una re!re$entaci:n de la ba$e de dato$ 0North.ind2:

#l di$eCo de arriba de=ine cuatro cla$e$: Product, ;ate(ory, 1rder y 1rderEetail+ La$ !ro!iedade$ de cada cla$e ma!ean la$ columna$ de cada table en la ba$e de dato$+ ;ada in$tancia de e$a cla$e re!re$enta una =ila en la$ tabla$+ La$ =lecha$ entre la$ cuatro cla$e$ de arriba re!re$entan la$ a$ociacione$>relacione$ entre la$ di=erente$ entidade$+ Son t'!icamente modelada$ como relacione$ !rimary-/ey>=orei(n-/ey en la ba$e de dato$+ La direcci:n de la$ =lecha$ en el di$eCador indican $i la relaci:n e$ uno-a-uno o uno-a-)ario$+ Se aCadiran !ro!iedade$ =uertemente ti!ada$ a la$ entidade$ ba$5ndo$e en e$to+ Por e7em!lo, la cla$e ;ate(ory de arriba tiene una relaci:n de uno-a-)ario$ con la cla$e Product+ #$to im!lica &ue tendr5 una !ro!iedad 0;ate(orie$2 &ue e$ una colecci:n de ob7eto$ Product con e$a cate(or'a+ La cla$e Product entonce$ tiene una !ro!iedad 0;ate(ory2 &ue a!unta a una in$tancia de la cla$e ;ate(ory re!re$entando la cate(or'a a la &ue !ertenece el !roducto+ #l !anel de la derecha del di$eCador LINQ to SQL contiene una li$ta de !rocedimiento$ almacenado$ &ue interact%an con nue$tro modelo de ba$e de dato$+ #n el e7em!lo de arriba hemo$ aCadido un SP@1; AProcedimiento almacenadoB 0GetProduct$Fy;ate(ory2+ ;omo entrada recibe un cate(oryIE, y de)uel)e una $ecuencia de Product como re$ultado+ *eremo$ c:mo llamar a e$te !rocedimiento almacenado en un e7em!lo+

Entendiendo la clase DataContext ;uando !ul$5i$ el boton 0$a)e2 del di$eCador de LINQ to SQL, *i$ual Studio (enerar5 cla$e$ +N#, !ara re!re$entar la$ entidade$ y la$ relacione$ de la ba$e de dato$ &ue hemo$ modelado+ Por cada archi)o aCadido a nue$tra $oluci:n !or el di$eCador LINQ to SQL tambi4n $e (enerar5 una cla$e Eata;onte9t+ #$ta cla$e e$ a tra)e$ de la cual reali6aremo$ la$ con$ulta$ a la$ entidade$ de nue$tra ba$e de dato$+ #$ta cla$e tendr5 !ro!iedade$ &ue re!re$entar5n a cada tabla &ue hemo$ modelado, a$' como m4todo$ !ara cada !rocedimiento almacenado &ue aCadamo$+ Por e7em!lo, a&u' ten4i$ la cla$e North.indEata;onte9t:

Ejemplos de LINQ to SQL Dna )e6 &ue hemo$ modelado nue$tra ba$e de dato$ con el di$eCador de LINQ to SQL, !odemo$ e$cribir c:di(o =5cilmente !ara traba7ar con 4l+ 3&u' ten4i$ uno$ cuanto$ e7em!lo$ &ue mue$tran tarea$ comune$ con dato$: 1 Consultando !"oducts de la base de datos #l $i(uiente c:di(o u$a una con$ulta LINQ !ara obtener una $ecuencia I#numerable de ob7eto$ Product+ -i75o$ &ue e$te c:di(o e$t5 con$ultando a tra)e$ de la relaci:n Product>;ate(ory !ara obtener a&uello$ !roducto$ de la cate(or'a 0Fe)era(e$2+ ;G:

*F:

# $ctuali%ando un p"oducto en la base de datos& #l c:di(o $i(uiente mue$tra c:mo obtener un !roducto de la ba$e de dato$, actuali6ar $u !recio, y (uardar lo$ cambio$ en la ba$e de dato$:

;G:

*F:

Nota: *F en 01rca$2 Feta1 no $o!orta Lambda$ a%n+ Pero en la Feta2 $' -de =orma &ue el c:di(o anterior $e !odr5 e$cribir de una =orma m5$ conci$a+ ' $(adi" una nue)a cate*o"+a , dos nue)os p"oductos en la base de datos& #l $i(uiente c:di(o mue$tra c:mo crear una nue)a cate(or'a, y entonce$ crear do$ nue)o$ !roducto$ y a$ociarlo$ a la nue)a cate(or'a+ Lo$ tre$ $on de$!u4$ (uardado$ en la ba$e de dato$+ -i7ao$ como no nece$itamo$ admini$trar manualmente la$ relacione$ !rimary/ey>=orei(n/ey+ S:lo tenemo$ &ue aCadir lo$ ob7eto$ Product en la colecci:n 0Product$2 de la cate(or'a, y lue(o aCadir el nue)o ob7eto ;ate(ory en la colecci:n de 0;ate(orie$2 del Eata;onte9t, LINQ to SQL $abr5 autom5ticamente crear la$ P->-H nece$aria$: ;G:

- .o"a" p"oductos de la base de datos& #l c:di(o $i(uiente mue$tra c:mo borrar todo$ lo$ !roducto$ ,oy de la ba$e de dato$: ;G:

*F:

/ Llama" a un p"ocedimiento almacenado& #l c:di(o $i(uiente mue$tra c:mo obtener entidade$ de la tabla Product $in u$ar una con$ulta LINQ, $ino llamando al !rocedimiento almacenado 0GetProduct$Fy;ate(ory2 &ue aCadimo$ a nue$tro modelo de dato$+ -i75o$ &ue cuando obtenemo$ lo$ re$ultado$ de la tabla Product, !odemo$ actuali6ar>borrarlo$ y llamar a db+Submit;han(e$AB !ara hacer la$ modi=icacione$ en la ba$e de dato$+ ;G:

*F:

0 1btene" p"oductos con pa*inado del lado del se")ido" #l c:di(o $i(uiente mue$tra c:mo im!lementar un !a(inado e=iciente en el lado $er)idor como !arte de una con$ulta LINQ+ D$ando lo$ o!eradore$ S/i!AB y ,a/eAB, $:lo de)oleremo$ 10 =ila$ de la ba$e de dato$ < a !artir de la =ila 200+ ;G:

*F:

2es3men: LINQ to SQL no$ !ermite modelar la ca!a de dato$ de nue$tra$ a!licacione$ de una =orma $im!le y lim!ia+ Dna )e6 &ue hayamo$ de=inido nue$tro modelo de dato$, !odemo$ reali6ar con$ulta$, in$ercione$, actuali6acione$ y borrado$ $obre ella de =orma =5cil y e=iciente+ #$!ero &ue e$ta introducci:n o$ haya abierto el a!etito de a!render m5$+ #n la$ !r:9ima$ $emana$ continuar4 e$ta $erie de !o$t e9!lorando el LINQ to SQL en m5$ detalle+

I0-mayo-2007 LINQ to SQL (2 Parte Definiendo nuestras clases del modelo de datos)
Publicado en +N#,, 3SP +N#,, LINQ, LINQ to SQL, *i$ual Studio a 12:0J am !or "uanma

#n la !rimera !arte de la $erie de !o$t $obre LINQ to SQL habl4 $obre 0K&u4 e$ LINQ to SQLL2 y )imo$ !or encima al(uno$ e$cenario$ &ue !ermite+ #n a&u4l !o$t !u$imo$ uno$ cuanto$ e7em!lo$ de c:di(o donde demo$tr5bamo$ c:mo me7orar la !arte de dato$ u$ando LINQ to SQL: ;:mo ;:mo ;:mo ;:mo

con$ultar una ba$e de dato$+ actuali6ar =ila$ en una ba$e de dato$ aCadir y relacionar )aria$ =ila$ en una ba$e de dato$+ eliminar =ila$ de la ba$e de dato$+

;:mo llamar a !rocedimiento$ almacenado$+ ;:mo obtener dato$ con !a(inaci:n en el $er)idor+

8e7oramo$ todo$ e$to$ e$cenario$ u$ando un modelo de cla$e$ de LINQ to SQL como 4$te:

#n e$te $e(undo !o$t de la $erie )amo$ a )er en m5$ detalle c:mo crear el modelo anterior con LINQ to SQL+ LINQ to SQL, el di$eCador de LINQ to SQL, y toda$ la$ caracter'$tica$ &ue e$tamo$ )iendo $aldr5n con la )er$i:n de +N#, I+M y en la relea$e de *i$ual Studio 01rca$2+

Pod4i$ $e(uir todo$ lo$ !a$o$ $i(uiente$ de$car(5ndo tanto *i$ual Studio 01rca$2 Feta 1 o *i$ual Neb Ee)elo!er #9!re$$ 01rca$2 Feta 1+ Pod4i$ in$talar la$ do$ y u$arla$ $in nin(%n !roblema con *i$ual Studio 200M+ C"ea" un nue)o modelo de datos LINQ to SQL Podemo$ aCadir un modelo de dato$ de LINQ to SQL a un !ro7ecto 3SP+N#,, ;la$$ Library o Nindo.$, con la nue)a o!ci:n 03dd Ne. Item2 $eleccionando 0LINQ to SQL2:

Seleccionando 0LINQ to SQL2 lan6ar5 el di$eCador de LINQ to SQL, y no$ !ermitir5 modelar la$ cla$e$ &ue re!re$enten una ba$e de dato$ relacional+ ,ambi4n crear5 una cla$ =uertemente ti!ada 0Eata;onte9t2 &ue tendr5 la$ !ro!iedade$ &ue re!re$entar5n cual&uier tabla &ue modelemo$ de la ba$e de dato$, a$' como m4todo$ !ara cada !rocedimiento almacenado &ue modelemo$+ ;omo de$cribimo$ en la !rimera !arte de e$ta $erie de !o$t, la cla$e Eata;onte9t e$ el conducto !rinci!al &ue u$aremo$ tanto !ara con$ultar la ba$e de dato$ como !ara (uardar lo$ cambio$ &ue ha(amo$+

3&u' ten4i$ una ca!tura de !antalla de un di$eCo LINQ to SQL 1@8 )ac'o, e$ lo &ue )er4i$ de$!ue$ de crear un nue)o modelo de dato$ LINQ to SQL:

Clases Entidad 4Entit, LINQ to SQL no$ !ermite modelar cla$e$ &ue ma!een una ba$e de dato$+ #$ta$ cla$e$ $on t'!icamente conocida$ como 0;la$e$ #ntidad2 Aen in(le$ 0#ntity ;la$$e$2B y a la$ in$tancia$ $e la$ conoce como 0#ntidade$2 Aen in(le$ 0#ntitie$2B+ La$ cla$e$ entidad ma!ean a tabla$ de una ba$e de dato$+ La$ !ro!iedade$ de una cla$e entidad normalmente ma!ean la$ columna$ de la tabla+ ;ada in$tancia de una cla$e entidad re!re$enta a una =ila de una tabla de la ba$e de dato$+ La$ cla$e$ entidad de=inida$ !or LINQ to SQL no tienen &ue deri)ar de una cla$e ba$e e$!ec'=ica, lo &ue $i(ni=ica &ue !ueden heredar de cual&uier ob7eto &ue &ueramo$+ ,oda$ la$ cla$e$ creada$ !or el di$eCador de LINQ to SQL $e de=inen como 0cla$e$ !arciale$2 < con lo &ue !odemo$, o!cionalmente, aCadir !ro!iedade$ adicionale$, m4todo$ y e)ento$+ 3 di=erencia de la caracter'$tica de EataSet>,able3da!ter &ue a!orta *S 200M, cuando u$amo$ el di$eCador de LINQ to SQL no tenemo$ &ue e$!eci=icar &u4 con$ulta$ SQL $e tiene &ue u$ar cuando creamo$ el modelo de dato$ y la ca!a de acce$o+ #n lu(ar de e$o, no$ centramo$ en de=inir la$ cla$e$ entidad, c:mo $e ma!ean con la ba$e de dato$, y la$ relacione$ entre ella$+ La im!lementaci:n del 1@8 de LINQ to SQL $e encar(ar5 de (enerar la l:(ica de e7ecuci:n SQL !or no$otro$ en tiem!o de e7ecuci:n !ara &ue !odamo$ interactuar y u$ar la$ entitade$ de dato$+ Podemo$ u$ar $inta9i$ de con$ulta$ LINQ !ara indicar c:mo con$ultar nue$tro modelo de dato$ de =orma =uertemente ti!ada+ C"ea" clases entidad de la base de datos& Si ya tenemo$ un e$&uema de ba$e de dato$ de=inido, !odemo$ u$arlo !ara crear cla$e$ entidad LINQ to SQL+

La =orma m5$ $encilla de con$e(uirlo e$ abrir la ba$e de dato$ de$de el 0Ser)er #9!lorer2 de *i$ual Studio, $eleccionar la$ tabla$ y )i$ta$ A*ie.$B &ue &ueramo$ modelar, y arra$trarla$ al di$eCador LINQ to SQL:

;uando aCadimo$ e$ta$ do$ tabla$ A;ate(orie$ y Product$B y una )i$ta AIn)oice$B de la ba$e de dato$ 0North.ind2 al di$eCador de LINQ to SQL, tendremo$ la$ $i(uiente$ cla$e$ entidad creada$ a !artir del e$&uema de la ba$e de dato$:

D$ando e$ta$ cla$e$, !odemo$ e7ecutar todo$ lo$ e7em!lo$ de c:di(o Ae9ce!to el de !rocedimiento$ almacenado$B &ue )imo$ en la !rimera !arte de e$ta $erie $obre LINQ to SQL+ No tenemo$ &ue aCadir nin(%n c:di(o adicional o con=i(uraci:n !ara habilitar lo$ e$cenario$ de con$ulta, in$erci:n, actuali6aci:n, borrado, y !a(inaci:n en el $er)idor+ Nomb"ado , plu"ali%aci5n Dna de la$ co$a$ de la$ &ue o$ dar4i$ cuenta u$anto el di$eCador de LINQ to SQL e$ &ue autom5ticamente 0!lurali6a2 lo$ nombre$ de la$ tabla$ y columna$ cuando crea la$ cla$e$ entidad ba$5da$ en el e$&uema de la ba$e de dato$+ Por e7em!lo: la tabla

0Product$2 del e7em!lo $e re$uel)e en una cla$e 0Product2, y la tabla 0;ate(orie$2 $e re$uel)e en la cla$e 0;ate(ory2+ #$te nombrado de cla$e$ hace &ue )ue$tro modelo $ea m5$ con$i$tente con la$ con)encione$ de nomenclatura de +N#,, y encuentro ba$tante %til &ue el di$eCador ha(a e$to !or mi Ae$!ecialmente cuando aCadimo$ mucha$ tabla$ a nue$tro modeloB+ Si no o$ (u$ta el nombre de una cla$e o !ro!iedad &ue el di$eCador ha (enerado, $iem!re !odr4i$ cambiarlo !or el &ue &uer5i$+ Pod4i$ hacerlo editanto el nombre de la entidad>!ro!iedad en el mi$mo di$eCador o cambiarlo en la re7illa de !ro!iedade$:

#$ta habilidad de nombrado de entidade$>!ro!iedade$>a$ociacione$ e$ muy %til en un (ran n%mero de ca$o$+ #n !articular: 1B ;uando cambie el nombre de una tabla>columna de )ue$tra ba$e de dato$+ ;omo )ue$tra$ entidade$ tendr5n nombre$ di=erente$, !od4i$ decidir actuali6ar la$ re(la$ de ma!eado y no el c:di(o de )ue$tra a!licaci:n o la$ con$ulta$ !ara u$ar e$a$ nue)a$ tabla$>columna$+ 2B ;uando en el e$&uema de la ba$e de dato$ ten(ai$ nombre$ &ue no $on 0lim!io$2+ Por e7em!lo, en lu(ar de u$ar 0auOlname2 y 0auO=name2 !ara lo$ nombre$ de la$ !ro!iedade$ en una cla$e entidad, !od4i$ u$ar lo$ nombre$ de 0La$tName2 y 0-ir$tName2 en )ue$tra$ cla$e$ entidad y !ro(ramar con e$o$ nombre$, en )e6 de cambiarlo en la ba$e de dato$+ 2elaciones ;uando arra$tremo$ ob7eto$ del 0$er)er e9!lorer2 al di$eCador 0LINQ to SQL2, *i$ual Studio com!robar5 la$ relacione$ de cla)e !rimaria y a7ena$ de lo$ ob7eto$, y ba$5ndo$e en ella$ crear5 relacione$ !or de=ecto entre la$ di=erente$ cla$e$ entidad &ue (enere+ Por e7em!lo, cuando aCadimo$ la$ tabla$ Product$ y ;ate(orie$ de la ba$e de dato$ NorthNind al di$eCador LINQ to SQL !odemo$ )er &ue $e ha deducido una relaci:n de uno a n entre ella$ Ae$to $e indica con la =elcha del na)e(adorB:

#$ta relaci:n har5 &ue la cla$e entidad Product ten(a una !ro!iedad llamada 0;ate(ory2 &ue lo$ de$arrolladore$ u$ar5n !ara acceder a la entidad ;ate(ory !ara un Product dado+ ,ambi4n har5 &ue la cla$e ;ate(ory ten(a una colecci:n de 0Product$2 &ue !ermitir5 a lo$ de$arrolladore$ obtener todo$ lo$ !roducto$ de una ;ate(ory+

Si no no$ (u$ta c:mo el di$eCador a nombrado a la relaci:n, $iem!re !odr4mo$ cambiarlo+ S:lo hay &ue hacer clic en la =elcha en el di$eCador, )er la$ !ro!iedade$ y cambiar el nombre+ 2et"asa" la ca"*a

LINQ to SQL !ermite a lo$ de$arrolladore$ e$!eci=icar $i la$ !ro!iedade$ de la$ entidade$ deben !recar(ar$e o retra$ar$e ha$ta el !rimer acce$o+ Podemo$ !er$onali6ar la$ re(la$ de !recar(a>retra$o !ara la$ !ro!iedade$ de la$ entidade$ $eleccionando cual&uier !ro!iedad o a$ociaci:n en el di$eCador, y en la$ !ro!iedade$ !oner la !ro!iedad 0Eelay Loaded2 a true o =al$e+ Por !oner un e7em!lo, ima(inemo$ la cla$e entidad 0;ate(ory2 del modelo anterior+ La tabla 0;ate(orie$2 de la ba$e de dato$ 0NorthNind2 tiene una columna 0Picture2 &ue contiene una ima(en A!otencialmente (randeB !ara cada cate(or'a, y $:lo &ueremo$ e$a ima(en cuando )aya a u$arla Ay no cuando e$t4 haciendo una con$ulta !ara obtener lo$ nombre$ de la$ cate(or'a$ en una li$taB+ Podr'amo$ con=i(urar la !ro!iedad Picture !ara &ue $e retra$e $u car(a $eleccionandola en el di$eCador de LINQ to SQL y en la$ !ro!iedade$ !oner 0Eelay Loaded2 a true:

Nota: 3dem5$ de con=i(urar el $i(ni=icado de la !recar(a>retra$o de la$ entidade$, !odemo$ $obree$cribirlo )'a c:di(o cuando ha(amo$ con$ulta$ LINQ en la$ cla$e$ entidad Alo )eremo$ en el $i(uiente !o$t de e$ta $erieB+

6sando p"ocedimientos almacenados& LINQ to SQL no$ !ermite modelar !rocedimiento$ almacenado$ como m4todo$ de nue$tra cla$e Eata;onte9t+ Por e7em!lo, $u!on(amo$ &ue hemo$ de=inido un !rocedimiento almacenado $im!le !ara obtener la in=ormaci:n de un !roducto de un cate(oryIE:

Podemo$ u$ar el $er)er e9!lorer de *i$ual Studio y arra$trar e$te !rocedimiento almacenado al di$eCador de LINQ to SQL !ara obtener un m4todo =uertemente ti!ado &ue in)ocar5 a e$te !rocedimiento almacenado+ Si lo arra$tramo$ encima de la entidad 0Product2 en el di$eCador, el di$eCador declarar5 &ue el !rocedimiento almacenado de)uel)e un I#numerablePProductQ:

Podemo$ u$ar tanto una con$ulta SQL A&ue (enerar5 una con$ulta SQL adhocB o in)ocar el !rocedimiento almacenado aCadido !ara obtener la$ entidade$ !roduct de la ba$e de dato$:

6sa" p"ocedimientos almacenados pa"a actuali%a"7bo""a"7inse"ta" datos& Por de=ecto LINQ to SQL crear5 autom5ticamente e9!re$ione$ SQL a!ro!iada$ !ara cuando ten(amo$ &ue in$ertar>actuali6ar>borrar entidade$+ Por e7em!lo, $i e$cribimo$ el $i(uiente c:di(o LINQ to SQL !ara actuali6ar al(uno$ )alore$ en una in$tancia de la entidad 0Product2:

LINQ to SQL crear5 y e7ecutar5 una $entencia 0DPE3,#2 a!ro!iada !ara cuando ace!temo$ lo$ cambio$ A*eremo$ e$to en m5$ !ro=undidad en otro$ !o$tB+

Podemo$ de=inir !rocedimiento$ almacenado$ !er$onali6ado$ !ara INS#@,, DPE3,#, E#L#,#+ Para con=i(urar e$to, hacemo$ clic en una entidad del di$eCador LINQ to SQL y en la$ !ro!iedade$ de Eelete>In$ert>D!date, en el bot:n 0R2, y !onemo$ un !rocedimiento almacenado &ue ya hayamo$ de=inido+

Lo curio$o e$ &ue el cambio de e$ta$ !ro!iedade$ $e e$t5 reali6ando en la ca!a de ma!eo de LINQ to SQL < lo &ue im!lica &ue la actuali6aci:n del c:di(o &ue )imo$ 5nte$ $i(ue =uncionando $in tener &ue hacer nin(una modi=icaci:n+ ;on e$to libramo$ a lo$ de$arrolladore$ de &ue $i cambiamo$ el modelo de dato$ LINQ to SQL, no tienen &ue tocar nin(%n c:di(o !ara &ue $i(ua =uncionando $i deciden !oner un !rocedimiento almacenado !er$onali6ado+ 2esumen LINQ to SQL !ro)ee una =orma lim!ia de modelar la$ ca!a$ de dato$ de nue$tra$ a!licacione$+ Dna )e6 &ue ten(amo$ nue$tro modelado de dato$, !odemo$ reali6ar de =orma e=iciente con$ulta$, in$ercione$, actuali6acione$, y borrado$ $obre 4l+ ;on el di$eCador de LINQ to SQL &ue )iene en *i$ual Studio y en *i$ual Neb Ee)elo!er #9!re$$ !odemo$ crear y admini$trar nue$tro$ model$o de dato$ !ara LINQ to SQL e9tremadamente r5!ido+ #l di$eCador LINQ to SQL tambi4n !ermite

una (ran =le9ibilidad &ue no$ !ermite !er$onali6ar el com!ortamiento !or de=ecto y $obree$cribir>e9tender el $i$tema !ara &ue $e ada!te a nue$tra$ nece$idade$+ #n !r:9imo$ !o$t u$aremo$ e$te modelo &ue hemo$ creado !ara )er en m5$ detalle lo$ !roce$o$ de con$ulta, in$ercione$, actuali6acione$ y borrado$+ #n e$to$ !o$t tambi4n )eremo$ c:mo aCadir )alidacione$ ne(ocio>dato$ !er$onali6ada$ a la$ entidade$ &ue hemo$ di$eCado+ 8i/e ,aulty tiene una (ran cantidad de )ideo$ $obre LINQ to SQL a&u', o$ recomiendo &ue lo$ )e5i$+ 3$' ten4i$ una =orma de a!render )iendo c:mo $e u$a LINQ to SQL+

I0-7unio-2007 LINQ to SQL (3 Parte Consultando la ase de datos)


Publicado en +N#,, 3SP +N#,, LINQ, LINQ to SQL, Scott Guthri a 1:0S !m !or "uanma

#l me$ !a$ado em!e64 una $erie de !o$t $obre LINQ to SQL+ LINQ to SQL e$ un =rame.or/ 1>@8 A1b7ect relational ma!!in(B &ue )iene como !arte del +N#, -rame.or/ I+M, &ue no$ !ermite modelar de =orma $encilla ba$e$ de dato$ relacionale$ con cla$e$ de +N#,+ Podemo$ u$ar, !or tanto, e9!re$ione$ LINQ tanto !ara con$ultar a la ba$e de dato$ como !ara actuali6ar>inertar>borrar dato$+ 3&u' ten4i$ lo$ enlace$ a lo$ !rimero do$ !o$t de e$ta $erie: D$ando LINQ to SQL A1T ParteB LINQ to SQL A2T Parte < Ee=iniendo nue$tra$ cla$e$ del modelo de dato$B

#n el !o$t de hoy )amo$ a )er en m5$ detalle c:mo u$ar el modelo de dato$ &ue creamo$ en la $e(unda !arte, y )eremo$ c:mo u$arlo !ara con$ultar dato$ en un !royecto 3SP+N#,+ Modelo de la base de datos No"t89ind con LINQ to SQL #n el $e(undo !o$t de la $erie )imo$ c:mo crear un modelo de cla$e$ LINQ to SQL u$ando el di$eCador de LINQ to SQL &ue )iene con *S 200 + 3&u' ten4i$ el modelo &ue creamo$ a !artir de la ba$e de dato$ de e7em!lo North.ind:

1bteniendo p"oductos& Dna )e6 &ue tenemo$ de=inido nue$tra$ cla$e$ del modelo de dato$, !odemo$ con$ultar y obtener =5cilmente dato$ de nue$tra ba$e de dato$+ LINQ to SQL no$ !ermite e$to u$ando la $int59i$ de con$ulta$ de LINQ $obre la cla$e North.indEata;onte9t &ue creamo$ con el di$eCador LINQ to SQL+ Por e7em!lo, !ara obtener e iterar $obre una $ecuencia de ob7eto$ Product !odemo$ e$cribir el $i(uiente c:di(o:

#n e$ta con$ulta hemo$ u$ado la $entencia 0.here2 en nue$tra con$ulta LINQ !ara de)ol)er a&uello$ !roducto$ de una cate(or'a+ #$tamo$ u$ando el cam!o>!ro!iedad ;ate(oryIE del !roducto !ara hacer el =iltro+ Dna de la$ co$a$ &ue no$ a!orta LINQ to SQL e$ &ue no$ da una total =le9ibilidad en c:mo con$ultar nue$tro$ dato$, y !odemo$ a!ro)echarno$ de la$ a$ociacione$ &ue hicimo$ cuando modelamo$ la$ cla$e$ de LINQ to SQL !ara hacer con$ulta$ m5$ naturale$ y rica$ $obre la ba$e de dato$+ Por e7em!lo, !odemo$ modi=icar el =iltro de la con$ulta !or el ;ate(oryName en lu(ar de !or el ;ate(oryIE con la $i(uiente con$ulta LINQ:

-i75o$ en c:mo e$tamo$ u$ando la !ro!iedad 0;ate(ory2 de cada ob7eto Product !ara =iltrarlo$ !or ;ate(oryName+ #$ta !ro!iedad =ue creada autom5ticamente !or LINQ to SQL ya &ue modelamo$ la$ cla$e$ ;ate(ory y Product con una relaci:n 0)ario$ a uno2 en la ba$e de dato$+

Por !oner otro e7em!lo del u$o de la$ relacione$ de nue$tro modelo, !odr'amo$ e$cribir la $i(uiente con$ulta LINQ !ara obtener a&uello$ !roducto$ &ue ten(an m5$ de cinco :rdene$ !ara ello$:

-i75o$ c:mo u$amo$ la colecci:n 01rderEetail$2 &ue LINQ to SQL cre: en cada cla$e Product Adebido a la relaci:n 1 a )ario$ &ue modelamo$ en el di$eCador LINQ to SQLB+ :isuali%ando consultas LINQ to SQL en el debu**e" Lo$ 1@8 como LINQ to SQL admini$tran autom5ticamente la creaci:n y la e7ecuci:n del c:di(o SQL cuando reali6amo$ con$ulta$ o actuali6acione$ $obre $u modelo de ob7eto$+ Dna de lo$ mayore$ !reocu!acione$ &ue tienen lo$ de$arrolladore$ $obre lo$ 1@8$ e$ 0K!ero &u4 c:di(o SQL $e e$t5 e7ecutandoL2 Dna de la$ co$a$ &ue hace LINQ to SQL e$ !oder )er e95ctamente &u4 c:di(o SQL $e e$t5 e7ecutando cuando e7ecutamo$ nue$tra a!licaci:n con el debu((er+ ;on la beta 2 de *S 200 !odemo$ u$ar el nue)o !lu(-in de )i$uali6aci:n LINQ to SQL !ara )er Ay te$tearB cual&uier con$ulta LINQ to SQL+ Sim!lemente aCadimo$ un brea/!oint y !a$amo$ el rat:n !or encima y hacemo$ clic en la lu!a !ara )i$uali6ar e$a con$ulta:

#Sto no$ mo$trar5 un cuadro de di5lo(o &ue no$ dir5 e9actamente la SQL &ue LINQ to SQL u$ar5 cuando $e e7ecute la con$ulta !ara obtener lo$ ob7eto$ Product:

Si !ul$amo$ el bot:n 0#9ecute2 de e$te di5lo(o no$ !ermitir5 e)aluar el SQL dentro del debu((er y no$ mo$trar5 lo$ re$ultado$ de la ba$e de dato$:

1b)iamente e$to hace realmente =5cil )er &u4 l:(ica de con$ulta$ SQL e$t5 reali6ando LINQ to SQL+ -i75o$ &ue !odemo$ $obree$cribir la SQL &ue LINQ to SQL e7ecutar5 $i &ueremo$ cambiarlo - $in embar(o, en el U V de lo$ ca$o$ creo &ue o$ darei$ cuenta de &ue el c:di(o SQL &ue LINQ to SQL e7ecuta e$ realmente bueno+

Enla%ando consultas LINQ to SQL a cont"oles $S!&NE; Lo$ re$ultado$ de la$ con$ulta$ LINQ im!lementa la inter=a6 I#numerable < la cual e$ una inter=a6 &ue lo$ controle$ de $er)idor de 3SP+N#, $o!ortan !ara enla6ar dato$+ Lo &ue im!lica &ue !odemo$ enla6ar lo$ re$ultado$ de cual&uier con$ulta LINQ, LINQ to SQL, o LINQ to ?8L a cual&uier control 3SP+N#,+ Por e7em!lo, !odemo$ declarar un control Pa$!:(rid)ie.Q en una !5(ina +a$!9 de la $i(uiente =orma:

Lue(o, !odemo$ enla6ar lo$ re$ultado$ de la con$ulta LINQ to SQL &ue e$cribimo$ ante$:

#$to (enerar5 una !5(ina como la $i(uiente:

2est"in*iendo los "esultados de la consulta& Wa$ta ahora, cuando e)aluamo$ una con$ulta de !roducto$, e$tamo$ obteniendo !or de=ecto toda$ la$ columna$ de dato$ nece$aria$ !ara cubrir la entidad de Product+ Por e7em!lo, e$ta con$ulta !ara obtener !roducto$:

#l re$ultado de e$ta con$ulta e$:

Normalmente $:lo &ueremo$ un $ubcon7unto de lo$ dato$ de cada !roducto+ Podemo$ u$ar la nue)a caracter'$tica &ue LINQ y lo$ com!iladore$ de ;G y *F tienen !ara indicar &ue $:lo &ueremo$ un $ubcon7unto de lo$ dato$, modi=icando la con$ulta LINQ to SQL de la $i(uiente =orma:

;on e$to obtendremo$ un $ubcon7unto de lo$ dato$ &ue $e obtienen de la ba$e de dato$ Acomo )emo$ con el )i$or del debu((erB:

Lo realmente %til de LINQ to SQL e$ &ue !odemo$ a!ro)echarno$ de la$ a$ociacione$ entre cla$e$ de nue$tro modelo de dato$ cuando re$trin(imo$ lo$ dato$+ #$to no$ !ermite e9!re$ar con$ulta$ %tile$ y muy e=iciente$+ Por e7em!lo, la $i(uiente con$ulta obtiene lo$ IE y lo$ nombre$ de la entidad Product, el n%mero total de !edido$ &ue hemo$ hecho de !roducto$, y lo$ $uma al total de !edido$ de Producto$:

La e9!re$i:n a la derecha de la !ro!iedad 0@e)enue2 e$ un e7em!lo del u$o delm4todo de e9ten$i:n 0Sum2 de LINQ+ ,oma una e9!re$i:n Lambda &ue de)uel)e el )alor de cada !edido de !roducto como ar(umento+ LINQ to SQL e$ li$to y e$ ca!a6 de tran$=ormar la e9!re$i:n LINQ anterior al $i(uiente SQL cuando e$ e)aluado Acon el )i$or del debu((erB:

La $entencia SQL anterior hace &ue lo$ )alore$ Num1rder$ y @e)enue $e calculen dentro del $er)idor SQL, y de)uel)e lo$ $i(uiente$ )alore$ de la ba$e de dato$ Arealmente r5!idoB:

Podemo$ enla6ar el re$ultado anterior a nue$tro (rid)ie.:

F,N < en ca$o de &ue o$ lo !re(unt4i$, tenemo$ intelli$en$e en *S 200 cuando e$cribimo$ e$to$ ti!o$ de re$triccione$ en la$ con$ulta$ LINQ:

#n e$te e7em!lo e$tamo$ declarando un ti!o an:nimo &ue u$a la iniciali6aci:n de ob7eto$ !ara amoldar y de=inir la e$tructura del re$ultado+ X $e(uimo$ teniendo intelli$en$e en *S 200 , che&ueo de com!ilaci:n y $o!orte !ara re=actorin( con e$to$ ti!o$ anonimo$:

!a*inando los "esultados de la consulta& Dna de la$ nece$idade$ m5$ comune$ en entorno$ .eb e$ la !o$ibilidad de hacer e=icientemente la !a(inanci:n en la$ inter=ace$ de u$uario+ LINQ tiene do$ m4todo$ de e9ten$i:n &ue !ermite hacer e$to de =orma =5cil y e=iciente < lo$ m4todo$ S/i!AB y ,a/eAB+ Podemo$ u$ar lo$ m4todo$ S/i!AB y ,a/eAB !ara indicar &ue $:lo &ueremo$ de)ol)er 10 ob7eto$ !roducto < de$de la =ila &ue le !a$emo$ como ar(umento:

-i75o$ &ue no aCadimo$ ni S/i!tAB ni ,a/eAB en la !rimera con$ulta < $ino &ue lo hacemo$ de$!u4$ de la con$ulta Acuando lo enla6amo$ a la =uente de dato$ del Grid*ie.B+ 8ucho$ me !re(untan 0K!ero e$to no $i(ni=ica &ue !rimero obtiene todo$ lo$ dato$ de la ba$e de dato$ y lue(o hace la !a(inaci:n Ae$to e$ maloBL2 No+ La cue$ti:n e$ &ue LINQ u$a un modelo de e7ecuci:n en di=erido, e$ decir, la con$ulta no $e e7ecuta ha$ta &ue $e itera $obre lo$ re$ultado$+ Dno de lo$ bene=icio$ de e$te modelo de e7ecuci:n en di=erido e$ &ue no$ !ermite crear con$ulta$ en )aria$ l'nea$ de c:di(o Alo &ue me7ora la claridadB+ ,ambi4n no$ !ermite crear la$ con$ulta$ de$!u4$ de otra$ < lo &ue no$ !ermite com!o$icione$ m5$ =le9ible$ y reutili6aci:n+ Dna )e6 &ue tenemo$ el m4todo FindProductAB, !odemo$ e$cribir el $i(uiente c:di(o en nue$tra !5(ina !ara obtener el 'ndice de inicio de la con$ulta y hacer &ue lo$ !roducto$ $ean !a(inado$ y mo$trado$ en el (rid)ie.:

#$to no$ dar5 una !5(ina de !roducto$, =iltrada !ara mo$trar a&uello$ !roducto$ &ue ten(an m5$ de cinco !edido$, mo$trando dato$ calculado$ din5micamente, y &ue $on !a(inable$ a !artir de una cadena de con$ulta:

Nota: ;uando traba7amo$ contra SQL 200M, LINQ to SQL u$ar5 la =unci:n SQL @1NOND8F#@AB !ara crear toda la l:(ica de !a(inaci:n en la ba$e de dato$+ #$to no$ a$e(ura &ue $:lo de)ol)er5 la$ 10 =ila$ de dato$ &ue &ueremo$ mo$trar en la !5(ina:

#$to hace realmente =5cil y e=iciente na)e(ar !or (rande$ cantidade$ de dato$+ 2esumen Wemo$ )i$to !or encima al(una de la$ co$a$ &ue LINQ to SQL no$ o=rece+ Para a!render m5$ $obre e9!re$ione$ LINQ y la$ nue)a$ caracter'$tica$ de con$ulta$ &ue traen lo$ com!iladore$ de ;G y *F con *S 200 , leed e$to$ !o$t:

Nue)a$ caracter'$tica$ de la nue)a )er$i:n de ;G 1rca$ 84todo$ de e9ten$i:n+ #9!re$ione$ Lambda Sinta9i$ de con$ulta$ ,i!o$ an:nimo$

#n el !r:9imo !o$t de e$ta $erie $obre LINQ to SQL )eremo$ c:mo !odemo$ aCadir l:(ica de )alidaci:n a nue$tro modelo de cla$e$ de dato$, y mo$traremo$ c:mo !odemo$ u$arlo !ara enca!$ular la l:(ica de ne(ocio &ue $e e7ecutar5 con cada actuali6aci:n, in$erci:n o borrado de nue$tro$ dato$+ *eremo$ ca$o$ m5$ a)an6ado$, c:mo u$ar el nue)o control Pa$!:LINQEataSourceQ !ara aCadir enlace$ de dato$ declarati)o$ a controle$ 3SP+N#,, re$oluci:n de errore$ de concurrencia o!timi$ta, y m5$+

1I-7ulio-2007 LINQ to SQL (! Parte) "ctuali#ando la ase de datos

Publicado en +N#,, 3SP +N#,, LINQ, LINQ to SQL, Scott Guthri, SQL, *i$ual Studio a M:02 !m !or "uanma

#n la$ %ltima$ $emana$ he e$crito una $erie de !o$t $obre LINQ to SQL+ LINQ to SQL e$ un 1>@8Aob7ect relational ma!!erB inte(rado en la )er$i:n I+M del =rame.or/ de +N#,, y no$ !ermite modelar =5cilmente ba$e$ de dato$ relacionale$ en cla$e$ de +N#,+ Podemo$ u$ar e9!re$ione$ LINQ tanto !ara con$ultar la ba$e de dato$ como !ara actuali6ar, in$ertar y borrar dato$+ 3&u' ten4i$ lo$ lin/$ a lo$ tre$ !rimero$ !o$t: Parte 1: Introducci:n a LINQ to SQL Parte 2: Ee=iniendo el modelo de dato$+ Parte I: ;on$ultando la ba$e de dato$

#n el !o$t de hoy )eremo$ c:mo u$ar el modelo de dato$ &ue hemo$ creado, y u$arlo !ara actuali6ar, in$ertar y borrar dato$+ ,ambi4n )eremo$ c:mo inte(rar re(la$ de ne(ocio y crear l:(ica de )alidaci:n !er$onali6ada con nuetro modelo de dato$+ Modelado de la base de datos No"t8<ind con LINQ to SQL #n la $e(undo !o$t de e$ta $erie, )imo$ c:mo crear el modelo de cla$e$ con el di$eCador de LINQ to SQL &ue trae *S 200 + 3&u' ten4i$ el modelo &ue creamo$ a !artir de la ba$e de dato$ de e7em!lo North.ind &ue u$aremo$ en e$te !o$t:

;uando de=inimo$ el modelo de=inimo$ cinco cla$e$: Product, ;ate(ory, ;u$tomer, 1rder y 1rderEetail+ La$ !ro!iedade$ de cada cla$e ma!ean la$ di=erente$ columna$ de la$ tabla$ corre$!ondiente$ en la ba$e de dato$+ ;ada in$tancia de cada cla$e e$ una entidad &ue re!re$enta una =ila de cada tabal+ ;uando de=inimo$ nue$tro modelo de dato$, el di$eCador LINQ to SQL cre: una cla$e llamada Eata;onte9t &ue !ro!orciona todo lo nece$ario !ara !oder con$ultar>actuali6ar la ba$e de dato$+ #n nue$tro e7em!lo, e$ta cla$e $e llama

North.indEata;onte9t+ Y$ta cla$e tiene una$ !ro!iedade$ &ue re!re$entan cada tabla modelada de la ba$e de dato$ Aen concreto: Product$, ;ate(orie$, ;u$tomer$, 1rder$ y 1rderEetail$B+ ;omo )imo$ en el tercer !o$t de e$ta $erie, !odemo$ u$ar e9!re$ione$ LINQ !ara con$ultar y obtener dato$ u$ando la cla$e North.indEata;onte9t+LINQ to SQL traduce autom5ticamente e$ta$ e9!re$ione$ LINQ al c:di(o SQL a!ro!iado en tiem!o de e7ecuci:n+ Por e7em!lo, la $i(uiente e9!re$i:n de)uel)e un ob7eto Product bu$cando el nombre del !roducto:

La $i(uiente con$ulta no$ de)uel)e todo$ lo$ !roducto$ de la ba$e de dato$ &ue no han $ido !edido$, y cuyo !recio e$ mayor de 100 d:lare$:

#$tamo$ u$ando la a$ociaci:n 01rderEetail$2 de cada !roducto como !arte de la con$ulta $:lo !ara obtener a&uello$ !roducto$ &ue no $e han !edido+ Se*ui" los cambios , DataContext&SubmitC8an*es4

;uando creamo$ con$ulta$ y obtenemo$ ob7eto$ como en lo$ e7em!lo$ anteriore$, LINQ to SQL e$tar5 !endiente de lo$ cambio$ o actuali6acione$ &ue le$ ha(amo$ a lo$ ob7eto$+ Podemo$ hacer tanta$ con$ulta$ y cambio$ como &ueramo$ u$ando la cla$e Eata;onte9t de LINQ to SQL, $abiendo &ue dicho$ cambio$ $er5n $u!er)i$ado$ a la )e6:
Nota: El seguimiento de cambios de LINQ to SQL ocurre en el lado del consumidor y NO en la base de datos. Es decir, no estamos consumiendo ningn recurso de la base de datos mientras lo usemos, tampoco tenemos que cambiar instalar nada en la base de datos para que esto !uncione.

Ee$!u4$ de reali6ar lo$ cambio$ &ue &ueramo$ a lo$ ob7eto$ &ue hemo$ obtenido con LINQ to SQL, !odemo$ llamar al m4todo 0Submit;han(e$AB2 de nue$tro Eata;onte9t !ara (uardar lo$ cambio$ en nue$tra ba$e de dato$+ ;on e$to, LINQ to SQL, creara y e7ecutar5 la$ $entencia$ SQL a!ro!iada$ !ara actuali6ar la ba$e de dato$+ Por e7em!lo, el $i(uiente c:di(o actuali6a el !recio y la$ unidade$ en $toc/ del !roducto 0;hai2 en la ba$e de dato$:

;uando llamamo$ al m4todo north.ind+Submit;han(e$AB, LINQ to SQL crear5 y e7ecutar5 la$ $entencia$ 0DPE3,#2 de SQL nece$aria$ !ara (uardar la$ !ro!iedade$ modi=icada$+ ;on el $i(uiente c:di(o iteramo$ $obre lo$ !roducto$ meno$ !o!ulare$ y caro$ y !onemo$ la !ro!iedad 0@eorderLe)el2 a cero+

;uando llamamo$ al m4todo north.ind+Submit;han(e$AB, LINQ to SQL crea y e7ecuta la$ $entencia$ DPE3,# de SQL nece$aria$ !ara modi=icar lo$ !roducto$ a lo$ &ue hemo$ modi=icado la !ro!iedad @eorderLe)el+ *emo$ &ue $i no $e ha modi=icado al(una !ro!iedad de un Product con la a$i(naci:n anterior, LINQ to SQL no e7ecutar5 nin(una actuali6aci:n !ara e$e ob7eto+ Por e7em!lo < $i el !recio del !roducto 0;hai2 era 2 dolare$, y el n%mero de unidade$ en $toc/ era cuatro, la llamada a Submit;han(e$AB no actuali6ara e$o$ )alore$+ S:lo lo$ !roducto$ cuyo @eorderLe)el no era 0 $e actuali6ar5n+ Ejemplos de inse"ci5n , bo""ado 3dem5$ de !oder actuali6ar la ba$e de dato$, LINQ to SQL tambi4n no$ !ermite in$ertar y eliminar dato$+ #$to lo con$e(uimo$ aCadiendo o eliminando ob7ecto$ de la$ coleccione$ di$!onible$ en Eata;onte$t, y lue(o llamar al m4todo Submit;han(e$AB+ LINQ to SQL 0monitori6ar52 e$a$ in$ercione$ y borrado$, y (enerar5 el c:di(o SQL nece$ario cuando $e in)o&ue a Submit;han(e$AB "#adiendo un producto Podemo$ aCadir un !roducto a la ba$e de dato$ creando un nue)o ob7eto 0Product2, iniciali6ando $u$ !ro!iedade$ y aCadirlo a la colecci:n 0Product$2 de nue$tro Eata;onte9t:

;uando llamemo$ a Submit;han(e$AB $e aCadir5 una nue)a =ila en la tabla de !roducto$+ $orrando productos Ee la mi$ma =orma &ue aCadimo$ un nue)o !roducto a la ba$e de dato$ aCadiendo un ob7eto Product a la colecci:n Product$ del Eata;onte9t, tambi4n !odemo$ borrar !roducto$ borr5ndolo$ de e$a mi$ma colecci:n:

Lo &ue e$tamo$ haciendo e$ obtener una $ecuencia de !roducto$ 0alternado$2 de la tabla, e$ decir, no ordenado$ !or nin(una e9!re$i:n LINQ, y lue(o e$a $ecuencia $e la !a$amo$ al m4todo @emo)e3llAB de la colecci:n 0Product$2+ ;uando llamamo$ a Submit;han(e$AB todo$ e$o$ !roducto$ $er5n borrado$ de la tabla $ctuali%aciones , "elaciones Lo &ue hace &ue lo$ 1>@8Z$ como LINQ to SQL $ean tan =le9ible$ e$ &ue tambi4n no$ !ermiten modelar la$ relacione$ entre la$ tabla$+ Por e7em!lo, !odemo$ modelar &ue cada !roducto ten(a una cate(or'a, &ue cada !edido ten(a un detalle de !edido, a$ociar cada detalle de !edido con un !roducto, y tener un con7unto de

!edido$ en cada cliente+ Xa )imo$ c:mo modelar la$ relacione$ en la $e(unda !arte de e$ta $erie de !o$t+ LINQ to SQL no$ !ermite a!ro)echar e$ta$ relacione$ tanto !ara con$ultar como !ara actuali6ar nue$tro$ dato$+ Por e7em!lo, con el $i(uiente c:di(o creamo$ un nue)o !roducto y lo a$ociamo$ con la cate(or'a 0Fe)era(e$2:

#$tamo$ aCadiendo el ob7eto !roducto en la colecci:n de cate(or'a$ de !roducto$+ #$to indicar5 &ue hay una relaci:n entre do$ ob7eto$, y har5 &ue LINQ to SQL manten(a autom5ticamente la$ relacione$ de cla)e !rimaria>a7ena entre lo$ do$ cuando llamemo$ a Submit;han(e$AB+ *eamo$ otro e7em!lo !ara )er c:mo LINQ to SQL no$ ayuda a mantener lim!io el c:di(o re=erente a la$ relacione$ entre la$ tabla$+ #n el $i(uiente e7em!lo e$tamo$ creando un nue)o !edido !ara un cliente e9i$tente+ Ee$!u4$ de rellenar la$ !ro!iedade$ nece$aria$, !odemo$ crear do$ ob7eto$ de detalle$ de !edido y a$ociarlo a un !edido de un cliente y actuali6aremo$ la ba$e de dato$ con todo$ lo$ cambio$:

;omo )emo$, el modelo de !ro(ramaci:n &ue hemo$ u$ado !ara hacer todo e$to e$ realmente lim!io y orientado a ob7eto$+ ;"ansacciones Dna tran$acci:n e$ un $er)icio de la ba$e de dato$ &ue (aranti6a &ue un con7unto de accione$ indi)iduale$ )an a $uceder de =orma at:mica < e$ decir, o $e !ueden com!letar toda$ o $i hay al(una &ue =alle, toda$ la$ dema$ $e de$cartar5n, y el e$tado de la ba$e de dato$ $er5 el mi$mo &ue 5nte$ de comen6ar la tran$acci:n+ ;uando llamemo$ a Submit;han(e$AB, la$ actuali6acione$ $e ma!ean en una %nica tran$acci:n+ #$ decir, la ba$e de dato$ no tendr5 nunca un e$tado incon$i$tente $i hacemo$ mucho$ cambio$ < tanto $i $e hacen la$ actuali6acione$ como $i no+

Si no hay nin(una tran$acci:n en cur$o, el ob7eto Eata;onte9t em!e6ar5 una tran$acci:n de la ba$e de dato$ !ara (uardar la$ actuali6acione$ &ue ha(amo$ con Submit;han(e$AB+ Pero LINQ to SQL tambi4n no$ !ermite de=inir e9!l'citamente y u$ar nue$tro !ro!io $i$tema de tran$accione$ Aintroducido en la )er$i:n 2+0 de +N#,B+ #$to hace m5$ =5cil a%n inte(rar c:di(o LINQ to SQL con el c:di(o de acce$o a dato$ &ue ya ten(amo$+ ,ambi4n no$ !ermite encolar recur$o$ &ue no $on !ro!io$ de la ba$e de dato$ en la mi$ma tran$acci:n - !or e7em!lo: !odemo$ en)iar un men$a(e 8S8Q, actuali6ar el $i$tema de archi)o$ Au$ando el nue)o $o!orte tran$accional de $i$tema$ de archi)o$B, etc < y enla6ar toda$ e$ta$ tarea$ en una $ola tran$acci:n a la hora de actuali6ar la ba$e de dato$ :alidaci5n , l5*ica de ne*ocio Dna de la$ co$a$ m5$ im!ortante$ &ue lo$ de$arrolladore$ tienen &ue hacer cuando traba7an con dato$ e$ incor!orar )alidaci:n y re(la$ de ne(ocio+ LINQ to SQL tiene )aria$ =orma$ !ara hacer &ue lo$ de$arrolladore$ !uedan hacer e$o de =orma =5cil y clara+ LINQ to SQL no$ !ermite aCadir e$ta )alidaci:n l:(ica una )e6+ Ee =orma &ue no tendremo$ &ue re!etir e$a l:(ica en )ario$ $itio$, con lo &ue con$e(uimo$ un modelo de dato$ m5$ mantenible y m5$ claro+ Sopo"te de )alidaci5n de es=uemas ;uando de=inimo$ el modelo de cla$e$ de dato$ con el di$eCador de LINQ to SQL de *S 200 , $e aCadir5n al(una$ re(la$ de )alidaci:n obtenida$ del e$&uema de la$ tabla$ de la ba$e de dato$+ Lo$ ti!o$ de dato$ de la$ !ro!iedade$ de la$ cla$e$ del modelo de dato$ coincidir5n con el e$&uema de la ba$e de dato$+ ;on e$to tendremo$ errore$ de com!ilaci:n $i intentamo$ a$i(nar un booleano a un )alor decimal, o $i con)ertirmo$ ti!o$ num4rico$ incorrectamente+ Si una columna en la ba$e de dato$ e$t5 marcada como nullable, la !ro!iedad corre$!ondiente &ue crea el di$eCador de LINQ to SQL $er5 un ti!o nullable+ La$ columna$ marcada$ como no nullable$ lan6ar5n e9ce!cione$ $i no le$ a$i(namo$ nin(un )alor+ LINQ to SQL tambi4n $e a$e(urar5 &ue de &ue lo$ )alore$ identidad>unico$ $e a$i(nan correctamente+

1b)iamente !odemo$ u$ar el di$eCador LINQ to SQL !ara $obree$cribir lo$ )alore$ !or de=ecto del e$&uema $i &ueremo$ < !ero !or de=ecto, la$ tendremo$ autom5ticamente $in tener &ue hacer nada+ LINQ to SQL tambi4n com!rueba lo$ )alore$ de lo$ !ar5metro$ de la$ con$ulta$ SQL, de manera &ue no tendremo$ &ue !reocu!arno$ !or lo$ ata&ue$ de inyecci:n de SQL+ Sopo"te pa"a )alidaci5n pe"sonali%ada de p"opiedades La )alidaci:n de dato$ a tra)4$ de e$&uema$ e$ muy %til, !ero no $uele $er $u=iciente en e$cenario$ reale$+ Ima(inemo$ &ue en la ba$e de dato$ North.ind tenemo$ una !ro!iedad 0Phone2 en la cla$e 0;u$tomer2 &ue e$t5 de=inida en la ba$e de dato$ como n)archar+ D$ando LINQ to SQL !odemo$ e$cribir el $i(uiente c:di(o !ara actuali6arlo con un n%mero de tel4=ono )5lido:

#l !roblema &ue no$ encontrar'amo$, $er'a &ue el $i(uiente c:di(o $i(ue $iendo )5lido de$de el !unto de )i$ta de un e$&uema SQL Aya &ue $i(ue $iendo una cadena, no un n%mero de tel4=ono )5lidoB+

Para no !ermitir &ue no $e !uedan meter n%mero$ de tel4=ono err:neo$ en nue$tra ba$e de dato$, !odemo$ aCadir una re(la de )alidaci:n !er$onali6ada a la cla$e ;u$tomer de nue$tro modelo de dato$+ #$ realmente =5cil, todo lo &ue nece$itamo$ hacer e$ aCadir una nue)a cla$e !arcial a nue$tro !royecto &ue de=ina el $i(uiente m4todo:

#$te c:di(o u$a do$ caracteri$tica$ de LINQ to SQL: 1+,oda$ la$ cla$e$ &ue (enera el di$eCador LINQ to SQL $on 0!arciale$2 < e$ decir, !odemo$ aCadir m4todo$ adicionale$, !ro!iedade$, y e)ento$ Aen archi)o$ $e!arado$B+ 3$' !odemo$ e9tender nue$tro modelo de cla$e$ creada !or el di$eCador de LINQ to SQL con re(la$ de )alidaci:n y m4todo$ au9iliare$ &ue de=inamo$+ No e$ nece$ario nin(una con=i(uraci:n+ 2. LINQ to SQL e9!one una $erie de !unto$ de e9ten$i:n en el modelo de dato$ &ue !odemo$ u$ar !ara aCadir )alidaci:n l:(ica+ 8ucho$ de e$to$ !unto$ de e9ten$i:n u$an la nue)a caracter'$tica llamada 0m4todo$ !arciale$2 &ue )iene con *F y ;G en *S 200 Feta2+ Ne$ Eyer el e&ui!o de ;G ha e$crito un !o$t e9!licando c:mo )a e$to de lo$ m4todo$ !arciale$+ #n nue$tro e7em!lo de )alidaci:n, e$tamo$ u$ando el m4todo !arcial 1nPhone;han(in &ue $e e7ecuta cada )e6 &ue $e cambia el )alor de la !ro!iedad 2Phone2 de un ob7eto 0;u$tomer2+ Podemo$ u$ar e$te m4todo !ara )alidar la entrada de dato$ Aen e$te ca$o e$tamo$ u$an una e9!re$i:n re(ularB+ Si todo )a bien, LINQ to SQL a$umir5 &ue el )alor e$ )5lido+ Si hay al(%n !roblema con el )alor, !odemo$ lan6ar una e9ce!ci:n en el m4todo de )alidaci:n < &ue har5 &ue la a$i(naci:n no $e ha(a+ Sopo"te pa"a )alidaci5n pe"sonali%ada de objetos entidad&

#n el !unto anterior hemo$ )i$to c:mo aCadir )alidaci:n a una !ro!iedad indi)idual de nue$tro modelo de dato$+ Sin embar(o, al(una$ )ece$, nece$itamo$>&ueremo$ )alidar )alidar multi!le$ !ro!iedade$ de un ob7eto+ *eamo$ un e7em!lo, tenemo$ un ob7eto 1rder y &ueremo$ !oner la$ !ro!iedade$ 01rderEate2 y 0@e&uiredEate2:

#$te c:di(o e$ le(al de$de el !unto de )i$ta de SQL < aun&ue no ten(a nin(%n $entido la !ro!iedad de =echa de entre(a, &ue era !ara ayer+ LINQ to SQL en Feta2 no$ !ermite aCadir re(la$ de )alidaci:n a ni)el de entidad !ara corre(ir e$te ti!o de errore$+ Podemo$ aCadir una cla$e !arcial !ara nue$tra entidad 01rder2 e im!lementar el m4todo !arcial 1n*alidateAB &ue $e in)ocar5 5nte$ de &ue $e (uarden lo$ dato$ en la ba$e de dato$+ Ee e$ta =orma, !odemo$ acceder y )alidar toda$ la$ !ro!iedade$ de nue$tro modelo de dato$:

Ee e$ta =orma !odemo$ )alidar cual&uiera de la$ !ro!iedade$ de la entidad Ainclu$o obtener acce$o de $:lo lectura a lo$ ob7eto$ a$ociado$B, y lan6ar una e9ce!ci:n $i el )alor e$ incorrecto+ ;ual&uier e9ce!ci:n lan6ada de$de el m4todo 1n*alidateAB

abortar5 cual&uier cambio &ue &ueramo$ hacer en la ba$e de dato$, y de$hacer todo$ lo$ cambio$ hecho$ en la tran$acci:n actual+ :alidaci5n en los mtodos de inse"ci5n7actuali%aci5n7bo""ado& 3 menudo nece$itamo$ aCadir )alidaci:n e$!ec'=ica en lo$ m4todo$ de in$erci:n, actuali6aci:n o borrado+ LINQ to SQL no$ lo !ermite aCadiendo una cla$e !arcial &ue e9tienda a la cla$e Eata;onte9t e im!lementar m4todo$ !arciale$ !ara !er$onali6ar la l:(ica de in$erci:n, actuali6aci:n y borrado de la$ entidade$ de nue$tro modelo de dato$+ #$to$ m4todo$ $er5n llamado$ autom5ticamente cuando in)o&uemo$ a Submit;han(e$AB+ Podemo$ aCadir la )alidaci:n l:(ica &ue e$timemo$ o!ortuna con e$to$ m4todo$ < y $i todo )a bien, LINQ to SQL continar5 (uardando lo$ dato$ en la ba$e de dato$ Allamando al m4todo de Eata;onte9t 0#9ecuteEynamic?X[2B+

Podemo$ aCadir m4todo$ &ue $e in)ocar5n autom5ticamente cuando $e )ayan a crear>actuali6ar>borrar dato$+ Por e7em!lo, $u!on(amo$ &ue &ueremo$ crear un nue)o !edido y a$ociarlo con un cliente e9i$tente:

;uando llamamo$ a north.ind+Submit;han(e$AB, LINQ to SQL determinar5 &ue e$ nece$ario (uardar el nue)o ob7eto 1rder, y e7ecutar5 nue$tro m4todo !arcial 0In$ert1rder2+ $)an%ado: :iendo la lista de cambios de la t"ansacci5n Way )ece$ &ue no no$ intere$a aCadir )alidaci:n l:(ica a elemento$ indi)iduale$, $ino &ue &ueremo$ $er ca!ace$ de )er toda la li$ta de cambio$ &ue e$t5n ocurriendo en una tran$acci:n+ Ee$de la Feta2 de +N#, I+M, LINQ to SQL no$ !ermite acceder a la li$ta de cambio$ a tra)4$ del m4todo Eata;onte9t+Get;han(eLi$tAB+ No$ de)ol)er5 un ob7eto ;han(eLi$t &ue e9!one una $erie de coleccione$ de adicione$, borrado$ y modi=icacione$ &ue $e han hecho+ Dna a!ro9imaci:n &ue !odemo$ hacer en al(uno$ e$cenario$ e$ crear una cla$e !arcial de la cla$e Eata;onte9t y $obree$cribir $u m4todo Submit;han(eAB+ Podemo$ obtener la li$ta de ;han(eLi$tAB !ara la$ o!eracione$ de actuali6acione$ y crear cual&uier )alidaci:n &ue &ueramo$:

#$te e7em!lo e$ un ca$o de u$o a)an6ado < !ero e$ intere$ante $aber &ue $iem!re !odremo$ e9tender y a!ro)echarno$ de e$ta =orma de la$ nue)a$ caracter'$tica$ de LINQ to SQL+ $dminist"ando cambios simult>neos con concu""encia optimista& Dna de la$ co$a$ en la$ &ue tenemo$ &ue !en$ar lo$ de$arrolladore$ en entorno$ multi-u$uario$ e$ c:mo admini$trar la$ actuali6acione$ de lo$ mi$mo$ dato$ en la ba$e de dato$+ Por e7em!lo, ima(inemo$ &ue tenemo$ do$ u$uario$ &ue obtienen un ob7eto !roduct, y uno de ello$ cambia el @eorderLe)el a 0 mientra$ &ue el otro lo !one a 1+ Si ambo$ u$uario$ (uardan e$o$ cambio$ en la ba$e de dato$, el de$arrollador tiene &ue decidir c:mo tratar e$e con=licto+ Dna $oluci:n e$ de7ar &ue $ea el %ltimo &ue lo (uarda < e$ decir, &ue el )alor &ue el !rimer u$uario (uard: $e !erder5 $in &ue 4$te $e de cuenta+ #$ta e$ una $oluci:n muy !obre Ae incorrectaB+ 1tra $oluci:n &ue !ermite LINQ to SQL e$ u$ar el modelo de concurrencia o!timi$ta, e$ decir, LINQ to SQL detectar5 autom5ticamente $i el )alor ori(inal de la ba$e de dato$ ha $ido actuali6ado !or al(uien 5nte$ &ue $e (uarden lo$ nue)o$ dato$+ LINQ to SQL no$ da una li$ta de con=licto$ de )alore$ cambiado$ al de$arrollador y no$ !ermite tanto hacer lo &ue &ueramo$ como a)i$ar al u$uario de la a!licaci:n !ara &ue no$ indi&ue el !ro!io u$uario lo &ue &uiere hacer+

Xa )eremo$ en m5$ detalle e$te tema en un !r:9imo !o$t+ 6so de p"ocedimientos almacenados o l5*ica SQL pe"sonali%ada pa"a inse"ta"? actuali%a" , bo""a"& Dna de la$ !re(unta$ &ue tienen lo$ de$arrolladore$ Aen e$!ecial lo$ EF3$B, &ue $uelen e$cribir !rocedimiento$ almacenado$ con SQL !er$onali6ada$, cuando )en LINQ to SQL !or !rimera)e6 e$: 0K!ero c:mo !odemo$ tener control ab$oluto del SQL &ue $e e$t5 e7ecutandoL2+ La$ buena$ noticia$ $on &ue LINQ to SQL tiene un modelo muy =le9ible &ue no$ !ermite $obree$cribir el SQL &ue $e e$t5 e7ecutando, y llamar a lo$ !rocedimiento$ almacenado$ &ue de$arrollemo$ !ara aCadir, actuali6ar o borrar dato$+ Lo realmente increible e$ &ue !odemo$ em!e6ar de=iniendo nue$tro modelo de dato$ y de7ar &ue LINQ to SQL admini$tre la$ in$ercione$, actuali6acione$ y borrado$+ Dna )e6 hecho e$to, !odemo$ !er$onali6ar el modelo de dato$ !ara &ue u$e nue$tro$ !ro!io$ !rocedimiento$ almacenado$ o nue$tra$ $entencia$ SQL < $in tener &ue cambiar nada de la l:(ica de a!licaci:n &ue e$tamo$ u$ando !ara nue$tro modelo de dato$, ni cambiar nada de la$ )alidacione$ ni de la l:(ica de ne(ocio+ #$to no$ da una (ran =le9ibilidad a la hora de con$truir nue$tra a!licaci:n+ Ee7aremo$ !ara otro !o$t c:mo !er$onali6ar lo$ modelo$ de dato$ con !rocedimiento$ almacenado$ o $entencia$ SQL+ 2esumen& #$te !o$t !re$enta un buen re$umen $obre c:mo !odemo$ u$ar LINQ to SQL !ara actuali6ar nue$tra ba$e de dato$ e inte(rar de una =orma clara )alidaci:n de dato$ y l:(ica de ne(ocio+ ;reo &ue encontrar4i$ &ue LINQ to SQL incrementa mucho la !roucti)idad a la hora de traba7ar con dato$, y no$ !ermite e$cribir c:di(o orientado a ob7eto claro en el acce$o a dato$+ #n !r:9imo$ !o$t )eremo$ el nue)o control Pa$!:lin&data$ourceQ de la )er$i:n I+M de +N#,, y hablaremo$ $obre lo =5cil &ue e$ crear inter=ace$ de u$uario en 3SP+N#, &ue $e a!ro)echen de lo$ modelo$ de dato$ de LINQ to SQL+ ,ambi4n )eremo$ al(uno$ conce!to$ de !ro(ramaci:n m5$ e$!eci=ico$ de LINQ to SQL $obre concurrencia o!timi$ta, car(a !ere6o$a, herencia de ma!eado de tabla$, u$o de !rocedimiento$ almacenado$ y $entencia$ SQL !er$onali6ada$, y mucho m5$+

1U-7ulio-2007 LINQ to SQL ($ Parte) %nla#ar controles de interfa# de usuario con el "SP&Lin'DatSource
Publicado en +N#,, 3SP +N#,, LINQ, LINQ to SQL, Scott Guthri, SQL, *i$ual Studio a 10:SI !m !or "uanma

#n la$ %ltima$ $emana$ he e$crito una $erie de !o$t $obre LINQ to SQL+ LINQ to SQL e$ un 1>@8 &ue )iene con la )er$i:n I+M del =rame.or/ +N#,, y no$ !ermite modelar ba$e$ de dato$ relacionale$ con cla$e$ de +N#,+ Podemo$ u$ar e9!re$ione$ LINQ !ara con$ultar la ba$e de dato$, a$' como actuali6ar, in$ertar y borrar dato$+ 3&u' ten4i$ lo$ lin/$ a lo$ !o$t anteriore$: Parte Parte Parte Parte

1: 2: I: S:

Introducci:n a LINQ to SQL Ee=iniendo el modelo de dato$+ ;on$ultando la ba$e de dato$ 3ctuali6ando la ba$e de dato$+

#n e$to$ !o$t hemo$ )i$to c:mo !odemo$ u$ar LINQ to SQL !ro(ram5ticamente !ara con$ultar y actuali6ar nue$tra ba$e de dato$+ #n el !o$t de hoy )eremo$ el nue)o control Pa$!:Lin&EataSourceQ de la nue)a )er$i:n del +N#, -rame.or/ AI+MB+ #$te control e$ una nue)a =uente de dato$ !ara 3SP+N#, Acomo lo$ controle$ 1b7ectEataSource y SQLEataSource de 3SP+N#, 2+0B &ue no$ )a a !ermitir enla6ar controle$ de la inter=a6 de u$uario a nue$tro modelo de dato$ LINQ to SQL+ $plicaci5n de ejemplo =ue const"ui"emos& #l e7em!lo &ue )eremo$ $e trata de una a!licaci:n muy $im!le &ue no$ )a a !ermitir editar lo$ dato$ de la tabla !roduct$:

La a!licaci:n le da al u$uario la$ $i(uiente$ o!cione$ de (e$ti:n: 1+-iltrado de !roducto$ !or cate(or'a$+ 2+1rdenar lo$ !roducto$ haciendo clic en la cabecera de la$ columna$ ANombre, Precio, unidade$ en $toc/, etcB I+Na)e(ar en !or lo$ !roducto$ de 10 en 10+ S+#dici:n de lo$ detalle$ de cual&uier !roducto+ M+Forrar !roducto$ de la li$ta+

La a!licaci:n .eb la im!lementaremo$ con un modelo de dato$ muy lim!io creado con el 1@8 LINQ to SQL+ ,oda$ la$ re(la$ de ne(ocio y la$ )alidacione$ l:(ica$ $e im!lementar5n en el la ca!a de dato$ < y no en la ca!a de !re$entaci:n ni en nin(una !5(ina .eb+ ;on e$to con$e(uiremo$: 1B Dn con7unto con$i$tente de re(la$ de ne(ocio &ue $er5n u$ada$ en toda la a!licaci:n, 2B e$cribiremo$ meno$ c:di(o y me7or a%n, no lo re!etiremo$ y IB !odremo$ cambiar la$ re(la$ de ne(ocio cuando &ueramo$ $in tener &ue actuali6ar e$e c:di(o en mile$ de $itio$ en toda la a!licaci:n+ ,ambi4n a!ro)echaremo$ el $o!orte de !a(inado y ordenaci:n de LINQ to SQL !ara a$e(urarno$ &ue tale$ o!eracione$ no $e reali6an en la ca!a intermedia, $ino en la ba$e de dato$ Ae$ decir, $:lo obtendremo$ 10 !roducto$ de la ba$e de dato$ en cada momento < no e$tamo$ obteniendo mile$ de =ila$ y orden5ndola$>!a(in5ndola$ en el $er)idor .ebB+ Qu es el cont"ol @asp:Lin=DataSou"ceA , c5mo nos a,uda? #l control Pa$!:Lin&EataSourceQ e$ un control de 3SP+N#, &ue im!lementa el!atr:n EataSource;ontrol &ue $e introdu7o con 3SP+N#, 2+0+ #$ $imilar a lo$ controle$ 1b7ectEataSource y S&lEataSource en &ue !uede enla6ar un control 3SP+N#, en una !5(ina con la ba$e de dato$+ La di=erencia e$ &ue en lu(ar de enla6ar directamente con la ba$e de dato$ Acomo el S&lEataSourceB o a una cla$e (en4rica Acomo el 1b7ectEataSourceB, e$te control e$t5 di$eCado !ara enla6ar aun modelo de dato$ con LINQ+ Dna de la$ )enta7a$ de u$ar e$te control e$ &ue ni)ela la =le9ibilidad de lo$ 1@8$ ba$ado$ en LINQ+ No tenemo$ &ue de=inir m4todo$ !ara in$erci:n>con$ulta>actuali6aci:n y borrado !ara el data$ource < $ino &ue aCadimo$ 4$te control a nue$tro modelo de dato$, de=inimo$ con &u4 entidade$ &ueremo$ &ue traba7e, y enla6amo$ cual&uier control de 3SP+N#, !ara &ue traba7e con 4l+ Por e7em!lo, !ara tener un li$tado b5$ico de lo$ !roducto$ &ue u$e la$ entidade$ Product con un modelo de dato$ LINQ to SQL, $:lo tenemo$ &ue declarar un control Pa$!:lin&data$ourceQ en nue$tra !5(ina &ue enla6e a la cla$e dataconte9t de nue$tro LINQ to SQL, identi=icar la$ entidade$ A!or e7em!lo: Product$B+ X ya !odemo$ enla6ar un Grid*ie. con 4l Amodi=icando $u !ro!iedad EataSourceIEB !ara obtener un (rid como el $i(uiente:

Sin tener &ue hacer nada m5$, !odemo$ e7ecutar la !5(ina y tener un li$tado de lo$ !roducto$ con !a(inado y ordenaci:n+ Podemo$ aCadir lo$ botone$ edit y delete en el (rid y tener $o!orte autom5tico !ara ello+ No tenemo$ &ue aCadir nin(%n m4todo, ma!ear nin(%n !ar5metro, ni e$cribir nin(%n c:di(o !ara el control Pa$!:Lin&EataSourceQ !ara tener toda$ e$ta$ o!eracione$+ ;uando $e hacen actuali6acione$, el 1@8 $e a$e(urar5 de &ue toda$ la$ re(la$ de ne(ocio y de )alidaci:n &ue hemo$ aCadido $e cum!lan 5nte$ de (uardar lo$ dato$+
Impo"tante: La belle6a de LINQ y LINQ to SQL e$ &ue ob)iamente no $:lo $ir)en !ara e$cenario$ como el anterior < o !ara ca$o$ !articulare$ !ara enla6ar controle$ de inter=ace$ de u$uario como con el Lin&EataSource+ ;omo ya hemo$ )i$to en lo$ !o$t anteriore$, e$cribir c:di(o con e$te 1@8 e$ muy lim!io+ Siem!re !odemo$ e$cribir c:di(o !er$onali6ado !ara nue$tra$ inter=ace$ de u$uario &ue traba7en directamente con el modelo de LINQ to SQL $i &ueremo$ o cuando no$ encontremo$ en un e$cenario en el &ue no $e !ueda u$ar Pa$!:lin&data$ourceQ

#n lo$ $i(uiente$ !a$o$ )eremo$ como montar la a!licaci:n &ue hemo$ de$crito u$ando LINQ to SQL y el control Pa$!:Lin&EataSourceQ !aso 1: DeBini" nuest"o modelo de datos #m!e6aremo$ de=iniendo el modelo de dato$ &ue u$aremo$ !ara re!re$entar la ba$e de dato$+ *imo$ c:mo de=inirlo en la $e(unda !arte de e$to$ art'culo$+ 3&u' ten4i$ una ca!tura de !antalla de la$ cla$e$ del modelo de dato$ creado con el di$eCador de LINQ to SQL de la ba$e de dato$ 0North.ind2:

*ol)eremo$ $obre nue$tro modelo de dato$ en el !a$o M de e$te tutorial cuando aCadamo$ al(una$ re(la$ de )alidaci:n de ne(ocio+ Pero !ara em!e6ar u$aremo$ el modelo de arriba+ !aso #: C"eaci5n de un listado b>sico de p"oductos& #m!e6aremo$ a crear la inter=a6 con una !5(ina 3SP+N#, con un control Pa$!:(rid)ie.Q con al(un e$tilo c$$:

Podr'amo$ e$cribir c:di(o !ara enla6ar !ro(ram5ticamente nue$tro modelo de dato$ al Grid*ie. Acomo hicimo$ en la tercera !arte de la $erieB, o !odemo$ u$ar el control Pa$!:lin&data$ourceQ !ara enla6ar el Grid*ie. al modelo de dato$+ *S200 no$ !ermite enla6ar nue$tro Grid*ie. Ao cual&uier control de $er)idor 3SP+N#,B (r5=icamente a dato$ LINQ+ Para hacerlo tenemo$ &ue !a$ar a la )i$ta de di$eCo, $eleccionar el Grid*ie. y ele(ir la o!ci:n 0Ne. Eata Source R2 en 0;hoo$e Eata Source2:

#$to no$ mo$trar5 un cuadro de di5lo(o con una li$ta de =uente$ de dato$ di$!onible$+ Seleccionamo$ la nue)a o!ci:n 0LINQ2 y le damo$ el nombre &ue &ueramo$:

#l di$eCador del control Pa$!:lin&data$ourceQ no$ mo$trar5 la$ cla$e$ Eata;onte9t de LINQ to SQL &ue hay di$!onible$ Aincluyendo a&uella$ &ue e$t5n en la$ librer'a$ &ue ten(amo$ re=erenciada$B:

Seleccionaremo$ el modelo &ue creamo$ con el di$eCador de LINQ to SQL+ Seleccionaremo$ la tabla &ue &ueramo$ &ue $ea la entidad !rinci!al con la &ue enla6ar el (rid+ #n nue$tro ca$o $eleccionaremo$ la cla$e Product$+ ,ambi4n $eleccionamo$ el boton 03d)anced2 y habilitaremo$ la$ actuali6acione$ y borrado$ !ara la =uente de dato$:

;uando ha(amo$ clic en el bot:n 0-ini$h2, *S 200 declarar5 un contorl Pa$!:lin&data$ourceQ en el +a$!9 y actuali6ar5 el (rid)ie. !ara &ue u$e e$ta =uente de dato$+ ,ambi4n (enerar5 la$ columna$ nece$aria$ !ara lo$ di=erente$ cam!o$ de la cla$e Product:

3hora de$!le(amo$ el 0$mart ta$/2 del (rid )ie. y le indicamo$ &ue &ueremo$ habilitar la !a(inaci:n, ordenado, edici:n y borrado:

Podemo$ !ular -M !ara e7ecutar la a!licaci:n, y )eremo$ una !5(ina con el li$tado de !roducto$ con !a(inaci:n y ordenado:

,ambi4n !odemo$ !ul$ar lo$ botone$ 0edit2 o 0delete2 en cada =ila !ara actuali6ar lo$ dato$:

Si !a$amo$ a la )i$ta de c:di(o de la !5(ina, )eremo$ la$ marca$ &ue contiene+ #l control Pa$!:lin&data$ourceQ a!unta a la cla$e Eata;onte9t, y a la tabla &ue le di7imo$ al !rinci!io+ #l Grid*ie. tiene como =uente de dato$ el control Pa$!:lin&data$ourceQ Aen el Eata$ourceIEB y le indica &u4 columna$ tienen &ue incluir$e en el (rid, cu5l e$ el te9to de la cabecera, y cual e$ la e9!re$i:n de ordenaci:n:

3hora tenemo$ lo b5$ico !ara em!e6ar a traba7ar con el com!ortamiento de e$ta inter=a6 de u$uario+ !aso ': Limpiando las columnas& #l (rid tiene mucha$ columna$, y do$ de ella$ Ael Su!!lierId y el ;ate(oryIEB $on cla)e$ a7ena$, &ue no con)iene mo$trar al u$uario+ Eliminando columnas innecesarias

#m!e6aremo$ eliminando al(una de la$ columna$ &ue no nece$itamo$+ Podemo$ hacer e$to en la )i$ta de c:di(oAborrando la declaraci:n de Pa$!:bound=ieldQ corre$!ondienteB o en la )i$ta de di$eCo Ahaciendo clic en la columna y $eleccionando la tarea 0remo)e2B+ Por e7em!lo, !odemo$ eliminar la columna 0QuantityPerDnit2 y e7ectuar la a!licaci:n:

Si hemo$ u$ado el contorl Pa$!:1b7ectEataSourceQ y le hemo$ indicado e9!l'citamente lo$ !ar5metro$ de actuali6aci:n Au!dateB a lo$ m4todo$ de actuali6aci:n A!or de=ecto cuando u$amo$ un EataSet ba$ado en ,able3da!ter$B una de la$ co$a$ &ue tenemo$ &ue hacer e$ cambiar la =irma de lo$ m4todo$ de actuali6aci:n del ,able3da!ter+ Por e7em!lo: $i eliminamo$ una columnan del (rid, tenemo$ &ue modi=icar el ,able3da!ter !ara &ue $o!orte lo$ m4todo$ de actuali6aci:n $in !ar5metro$+ ;on el control Pa$!:Lin&EataSourceQ e$ &ue no tendr'amo$ &ue hacer e$te ti!o de cambio$+ Sim!lemente borrando Ao aCadiendoB una columna a la inter=a6 de u$uario y e7ecutamo$ la a!licaci:n -no hacen =alta m5$ cambio$+ ;on e$to con$e(uimo$ &ue lo$ cambio$ &ue $e ha(an en la inter=a6 de u$uario $ean mucho m5$ =5cile$, y no$ !ermite iteracione$ m5$ r5!ida$ en nue$tra a!licaci:n+

Limpiando las columnas SupplierId y %ategoryI& Wa$ta ahora e$tamo$ mo$trando )alore$ entero$ de la$ cla)e$ a7ena$ en nue$tro Grid*ie. !ara lo$ cam!o$ Su!!lier y ;ate(ory:

Ee$de el !unto de )i$ta del modelo de dato$ e$ correcto, !ero no de$de el !unto de )i$ta del u$uario+ Lo &ue &ueremo$ hacer e$ mo$trar el nombre de la cate(or'a y el nombre del !ro)eedor, y mo$trar una li$ta de$!le(able en modo edici:n !ara &ue !odamo$ cambiar e$ta$ a$ociacione$ de =orma =5cil+ Podemo$ cambiar el (rid)ie. !ara &ue mue$tre el nombre del !ro)eedor y el de la cate(or'a en lu(ar del IE, cambiando el Pa$!:Found-ieldQ !or un Pa$!:,em!late-ieldQ+ X en e$te tem!late-ield aCadimo$ el contenido &ue &ueramo$ !ara !er$onali6ar la )i$ta de la columna+ #n el c:di(o $i(uiente a!ro)echaremo$ la ca!acidad de LINQ to SQL, &ue model: e$te cam!o como una !ro!iedad+ #$ decir, !o$demo$ enla6ar de =orma =5cil la$ !ro!iedade$ Su!!lier+;om!anyName y ;ate(ory+;ate(oryName al (rid:

3hora e7ecutamo$ la a!licaci:n y tenedremo$ lo$ )alore$ de ;ate(ory y Su!!lier de la $i(uiente =orma:

Para tener una li$ta de$!le(able en e$to$ do$ cam!o$ en el modo edici:n, tenemo$ &ue aCadir do$ controle$ Pa$!:Lin&EataSourceQ a la !5(ina+ Lo$ con=i(uraremo$ !ara &ue $e enlacen a la$ entidade$ ;ate(orie$ y Su!!lier$ del modelo de dato$ creado !or LINQ to SQL:

3hora )ol)emo$ a la columna$ Pa$!:,em!late-ieldQ &ue aCadimo$ ante$ y !er$onali6aremo$ la !arte de edici:n Ae$!eci=icando un #ditItem,em!lateB+ Ee

=orma &ue tendremo$ una li$ta de$!le(able en la )i$ta edici:n, donde lo$ )alore$ di$!onible$ $e obtendr5n de la$ =uente$ de dato$ de cate(or'a$ y !ro)eedore$, y enla6aremo$ doblemente el )alor $eleccionado al Su!!lierId y ;ate(oryIE de la$ cla)e$ a7ena$:

X ahora, cuando el u$uario ha(a clic en el bot:n de edici:n, $e mo$trar5 una li$ta con todo$ lo$ !ro)eedore$ di$!onible$:

X cuando $al)emo$ lo$ cambio$ $e (uardar5 el )alor $eleccionado en la li$ta de$!le(able+ 'aso (: )iltrando el listado de productos.

85$ &ue mo$trar todo$ lo$ !roducto$ de la ba$e de dato$, !odemo$ actuali6ar la inter=a6 de u$uario !ara incluir una li$ta de$!le(able &ue !ermita al u$uario =iltrar lo$ !roducto$ !or una cate(or'a !articular+ ;omo ya aCadimo$ un Pa$!:Lin&EataSourceQ enla6ada a la$ ;ate(or'a$ de nue$to modelo de LINQ to SQL, $:lo tendremo$ &ue crear un nue)o control de li$ta de$!le(able y enla6arlo+ Por e7em!lo:

;uando e7ecutemo$ la !5(ina tendremo$ un =iltro con toda$ la$ cate(or'a$ al !rinci!io de la !5(ina:

Lo %ltimo &ue &ueda e$ &ue cuando $eleccionemo$ una cate(or'a $e mue$tren lo$ !roducto$ de dicha cate(or'a en el (rid)ie.+ Lo m5$ =acil e$ $eleccionar la o!ci:n de 0;on=i(ure EataSource2 en el $mart ta$/ del Grid*ie.:

;on e$to )eremo$ el cuadro de dialo(o !ara con=i(urar el Pa$!:Lin&EataSourceQ &ue u$amo$ al !rinci!io del tutorial+ Seleccionamo$ el bot:n 0Nhere2 !ara aCadir un cam!o de =iltro al data$ource+ Podemo$ aCadir cual&uier n%mero de e9!re$ione$, y declarati)amente a$i(nar lo$ )alore$ con lo$ &ue =iltrar A!or e7em!lo: de una &uery$trin(, de )alore$ de =ormulario, de cual&uier control en la !5(ina, etcB+

*amo$ a !oner un =iltro de !roducto$ !or $u ;ate(oryIE, y obtenemo$ el )alor con el &ue =iltrar de la li$ta de$!le(able &ue creamo$ ante$:

;uando le damo$ a 0-ini$h2, el contorl Pa$!:lin&data$ourceQ $e actuali6ar5 !ara re=le7ar lo$ cambio$ de =iltrado:

X cuando e7ecutamo$ la a!licaci:n el u$uario $er5 ca!a6 de ele(ir una cate(or'a en la li$ta de =iltrado y !a(inar, ordenar, editar y borrar lo$ !roducto$ de una cate(or'a:

#l control Pa$!:Lin&EataSourceQ a!licar5 la$ e9!re$ione$ LINQ nece$aria$ !ara &ue cuando $e e7ecute contra el modelo de dato$ LINQ to SQL $:lo $e obten(an lo$ dato$ nece$ario$ de la ba$e de dato$ A!or e7em!lo: en el (rid anterior $:lo obtendremo$ I =ila$ con lo$ !roducto$ de la cate(or'a ;on=ectionB+ ,ambi4n !odemo$ (e$tionar no$otro$ el e)ento Selectin( $i &ueremo$ e$cribir e9!re$ione$ LINQ !er$onali6ada$+ 'aso *: "#adir reglas de +alidaci,n de negocio ;omo ya )imo$ en la cuarta !arte de e$ta $erie de !o$t, cuando de=inimo$ modelo$ de dato$ con LINQ to SQL tendremo$ un con7unto de e$&uema$ de )alidaci:n !or de=ecto en el modelo de cla$e$+ #$ decir, $i intentamo$ meter un )alor nulo en una columna re&uerida, intentar a$i(nar un $trin( a un entero, o a$i(nar una )alor de cla)e a7ena en una =ila &ue no e9i$ta, el modelo lan6ar5 un error y $e a$e(urar5 de &ue la inte(rar de la ba$e de dato$ $e mantiene+ #l e$&uema b5$ico de )alidaci:n e$ $:lo el !rimer !a$o, y e$ muy raro en la mayor'a de a!licacione$ reale$+ Normalmente nece$itaremo$ aCadir re(la$ adicionale$ a nue$tro modelo de dato$+ 3=ortunadamente con LINQ to SQL !odemo$ aCadir e$ta$ re(la$ de =orma muy =5cil A!ara m5$ detalle$ $obre e$te tema, leed la cuarta !arte de e$ta $erie de !o$tB+ E-emplo de escenario con reglas de +alidaci,n

Por e7em!lo, $u!on(amo$ una re(la b5$ica &ue &ueramo$ re=or6ar+ Queremo$ &ue un u$uario de nue$tra a!licaci:n no !ueda interrum!ir un !roducto mientra$ haya unidade$ !edida$:

Si un u$uario intenta (uardar la =ila anterior, &ueremo$ !re)enir &ue e$e cambio $e (uarde en la ba$e de dato$ y &ue (enere un error !ara &ue el u$uario lo arre(le+ "#adiendo una regla de +alidaci,n al modelo de datos. #l $itio incorrecto !ara aCadir e$te ti!o de )alidaci:n e$ en la ca!a de !re$entaci:n+ 3Cadirlo en e$ta ca!a im!lica &ue e$ta re(la $er5 $:lo )5lida en un lu(ar concreto, y no $er5 autom5tico en cual&uier !arte de la a!licaci:n+ Ei$tribuir la l:(ica de ne(ocio en la ca!a de !re$entaci:n tambi4n har5 &ue nue$tra )ida $ea realmente !eno$a a medida &ue nue$tra a!licaci:n cre6ca < ya &ue cual&uier cambio>actuali6aci:n en nue$tro ne(ocio hara nece$ario$ cambio$ de codi(o en toda$ !arte$+ #l lu(ar correcto !ara e$te ti!o de )alidaci:n e$ en la$ cla$e$ del modelo de dato$ de LINQ to SQL+ ;omo ya )imo$ en la cuarta !arte de e$ta $erie, toda$ la$ cla$e$ $e (eneran !or el di$eCador de LINQ to SQL como cla$e$ !arciale$ < con lo &ue !odemo$ aCadir m4todo$>e)ento$>!ro!iedade$ =5cilmente+ #l modelo de LINQ to SQL e7ectuar5 lo$ m4todo$ de )alidaci:n &ue !odemo$ im!lementar+ Por e7em!lo, Podemo$ aCadir una cla$e !arcial Product a nue$tro !royecto &ue im!lemente el m4todo !arcial 1n*alidateAB &ue LINQ to SQL llama ante$ de (uardar la$ entidade$ de Product+ #n e$te m4todo !odemo$ aCadir la $i(uiente re(la de ne(ocio !ara $e(urarno$ &ue lo$ !roducto$ no !ueden tener un @eorder Le)el $i el !roducto e$ di$continued:

Dna )e6 &ue aCadimo$ la cla$e anterior al !royecto LINQ to SQL, la re(la anterior $e com!robar5 cada )e6 &ue al(uien u$e nue$tro modelo de dato$ e intente modi=icar la ba$e de dato$+ #$to $e hace tanto !ara lo$ !roducto$ e9i$tente$ &ue $e )ayan a actuali6ar como !ara lo$ &ue $e )ayan a aCadir nue)o$+ ;omo el Pa$!:Lin&E3taSourceQ traba7a contra nue$tro modelo de dato$, cada actuali6aci:n>in$erci:n>borrado !a$ar5 !or e$ta re(la de )alidaci:n ante$ de (uardar lo$ cambio$+ No nece$itamo$ hacer nada m5$ en la ca!a de !re$entaci:n !ara &ue $e cum!la e$ta re(la < $e com!robar5 cada )e6 &ue $e u$e nue$tro modelo de dato$+ "#adir un mane-ador de errores en la capa de presentaci,n. Por de=ecto $i un u$uario u$a nue$tro Grid*ie. !ara meter una combinaci:n no )5lida de Dnit1n1rder>Ei$continued, nue$tro modelo LINQ to SQL lan6ar5 una e9ce!ci:n+ #l Pa$!:Lin&EataSourceQ ca!turar5 la e9ce!ci:n y no$ !ro!orciona un e)ento &ue !odemo$ u$ar !ara controlarlo+ Si nadie u$a el e)ento, el contol Grid*ie. Au otroB enla6ado al Pa$!:Lin&EataSourceQ ca!turar5 el error y !ro)eer5 un e)ento !ara controlarlo+ Si nadie controla el error $er5 !a$ado al mane7ador d ela !5(ina, y $i nadie lo controla, $e le !a$ar5 al e)ento 3!!licationO#rrorAB en el archi)o Global+a$a9+ Lo$ de$arrolladore$ !ueden hacer e$to en cual&uier !a$o del camino !ara aCadir la l:(ica de errore$ &ue &ueramo$ en la ca!a de !re$entaci:n+ Para la a!licaci:n &ue e$tamo$ )iendo, $e(uramente el me7or lu(ar !ara controlar cual&uier error de actuali6aci:n $ea en el )ento ro.D!dated del (rid*ie.+ #$te e)ento $e e7ectuar5 cada )e6 &ue $e actuali6e en nue$tro data$ource, y !odemo$ )er lo$ detalle$ de la e9ce!ci:n $i =alla la actuali6aci:n+ Podemo$ aCadir el $i(uiente

c:di(o !ara com!robar $i ha ocurrido un error, y mo$trar un error adecuado en ca$o de &ue ocurra:

No hemo$ tenido &ue aCadir nin(una )alidaci:n l:(ica en nue$tra inter=a6 de u$uario+ #n lu(ar de e$o, e$tamo$ obteniendo el error &ue lan6amo$ en nue$tra l:(ica de ne(ocio y la e$tamo$ u$ando !ara mo$trar un men$a7e adecuado al u$uario A#$tamo$ mo$trando un error m5$ (en4ricoB+ ,ambi4n le e$tamo$ indicando &ue &ueramo$ &ue el Grid*ie. $e manten(a en el modo edici:n cuando ocurra un error < de =orma &ue !odemo$ e)itar &ue el u$uario !ierda lo$ cambio$ &ue e$taba haciendo, y modi=icar lo$ )alore$ y darle a 0u!date2 otra )e6 e intentar (uardarlo+ Podemo$ aCadir un control Pa$!:literalQ en el 0#rror8e$$a(e2 en cual&uier !arte de la !a(ina &ue &ueramo$ !ara controlar donde &ueremo$ &ue $e mue$tre el error:

X ahora cuando intentemo$ actuali6ar un !roducto con )alore$ erroneo$ )eremo$ un men$a7e de error &ue indica c:mo arre(larlo:

Lo bueno de e$to e$ &ue !odemo$ aCadir o cambiar la$ re(la$ de ne(ocio $in tener &ue cambiar nada en la ca!a de !re$entaci:n+ La$ re(la$ de )alidaci:n, y $u$ men$a7e$ corre$!ondiente$, !ueden centrali6ar$e en un lu(ar en concreto del modelo de dato$ y $e a!licar5n en toda$ !arte$+ 2esumen #l control Pa$!:Lin&EataSourceQ no$ da una =orma =5cil de enla6ar controle$ de 3SP+N#, a nue$tro modelo de LINQ to SQL+ Permite obtener>actuali6ar>in$ertar>borrar dato$ del modelo de dato$+ #n nue$tra a!licaci:n hemo$ u$ado el 1@8 LINQ to SQL !ara crear un modelo lim!io, orientado a ob7eto$+ 3Cadimo$ tre$ contorle$ 3SP+N#, a la !5(ina Aun (rid*ie., una li$ta de$!le(able, y un errorme$$a(e literalB, y hemo$ aCadido tre$ contorle$ Pa$!:Lin&EataSourceQ !ara enla6ar a Product, ;ate(ory y Pro)eedore$:

#$cribimo$ M l'nea$ de )alidaci:n l:(ica y 11 linea$ !ara la (e$ti:n de errore$+ #l re$ultado =inal e$ una a!licaci:n .eb $im!le &ue !ermite a lo$ u$uario$ =iltrar lo$ !roducto$ !or $u cate(or'a, ordenar y !a(inar e=icientemente dicho$ !roducto$, editar lo$ !roducto$ y (uardarlo$ Acon nue$tra re(la$ de ne(ocioB, y borrar !roducto$ del $i$tema Atambi4n con nue$tra l:(ica de ne(ocioB+

#n !r:9imo$ !o$t )eremo$ en !ro=undidad al(uno$ e$cenario$ con concurrencia o!timi$ta, car(a a !etici:n, herencia de ma!eado de tabla$, y el u$o de !rocedimiento$ almacenado$ y SQL !er$onali6ado$+ La !r:9ima $emana ten(o !en$ado em!e6ar otra $erie de !o$t $obre el control Pa$!:Li$t*ie.Q < e$ un nue)o control de 3SP+N#, en la )er$i:n +N#, I+M+ No$ !ermite un contorl total $obre el c:di(o (enerado !ara e$cenario$ de dato$ A$in tabla$, $in $!an$, ni e$tilo$ en linea RB, tambi4n )eremo$ el $o!orte !ara !a(inaci:n, ordenado, edici:n e in$ercione$+ Por e7em!lo, !odemo$ u$arlo en lu(ar del Grid con un loo/ and =eel totalmente !er$onali6ado+ Lo me7or de todo, !odemo$ cambiar el c:di(o de la !5(ina anterior $in tener &ue cambiar nada del modelo de dato$, la declaraci:n del Pa$!:lin&data$ourceQ, o el code-behind del trato de errore$+

27-abril-200 Parte (& Crear la )ersi*n de escritorio con +P,


Publicado en Scott Guthri, Sil)erli(ht, N!= a 2:S1 !m !or "uanma

#$te e$ el %ltimo de lo$ ocho tutoriale$ en el &ue e$tamo$ creando un cliente de Ei(( con la Feta 1 de Sil)erli(ht 2+ La idea e$ &ue e$to$ tutoriale$ $e lean en orden, con el ob7eti)o de e9!licar lo$ =undamento$ de la !ro(ramaci:n con Sil)erli(ht+ Pod4i$ de$car(ar el c:di(o com!leto del cliente Ei(( del e7em!lo a&u' C"ea" una aplicaci5n de esc"ito"io con <!C #l ob7eti)o con e$te %ltimo tutorial e$ un !oco di=erente del de lo$ otro$ $iete+ No )amo$ a u$ar Sil)erli(ht en e$te !o$t < $ino &ue u$aremo$ NP- y +N#, I+M+ ;o7eremo$ el c:di(o de la a!licaci:n &ue e$tamo$ creando con Sil)erli(ht y lo reutili6aremo$ como una a!licaci:n de e$critorio+ Sil)erli(ht )iene con un $ubcon7unto com!atible de la 3PI del +N#, -rame.or/+ Dno de lo$ ob7eti)o$ de e$to e$ !ermitir a lo$ de$arrolladore$ a!render un mi$mo modelo de !ro(ramaci:n &ue le$ !ermita reu$ar c:di(o y contenido rico, tanto !ara la .eb como !ara a!licacione$ e$critorio+ 3&u' ten4i$ lo$ !a$o$ &ue he hecho !ara con)ertir la a!licaci:n Sil)erli(ht &ue hemo$ creado A&ue $e e7ecuta en un na)e(adorB en una a!licaci:n de e$critorio Nindo.$ A&ue no $e e7ecuta en el na)e(adorB+ !aso 1: C"ea" una nue)a aplicaci5n <!C de esc"ito"io #m!e6amo$ creando una nue)a a!licaci:n NP- con *S 200 + La llamaremo$ 0Ei((Ee$c/to!Sam!le2:

#$to crear5 un !royecto en *S con do$ archi)o$ < un 3!!+9aml y un Nindo.+9aml:

!aso #: Copia" el c5di*o existente en la aplicaci5n <!C ;o!iaremo$ y !e(aremo$ el c:di(o &ue ya tenemo$ en Sil)erli(ht en nue$tro nue)o !royecto:

#n la Feta1 e$ta !arte de co!iar y !e(ar e$ un !a$o manual < e$tamo$ )iendo la !o$ibilidad de tener una =orma m5$ autom5tica de hacer e$to+ !aso ': Co""e*i" un pa" de cositas We tenido &ue hacer do$ cambio$ !ara &ue nue$tro c:di(o com!ile: 1B #l e$&uema de Sil)erli(ht Feta1 9mln$: la url e$ di=erente de la )er$i:n de NP-+ We tenido &ue corre(ir e$to en lo$ archi)o$ ?38L &ue hemo$ co!iado en el !royecto !ara &ue a!unten al e$&uema de NP-+ #$to e$ al(o &ue e$tamo$ me7orando ante$ de !ublicarlo+ 2B We tenido &ue cambiar el control PNater8ar/,e9tbo9Q a un P,e9tFo9Q y cambiar el control PWy!erlin/FuttonQ !ara &ue $ea un P,e9tFloc/Q+ #$to$ do$ controle$ $on nue)o$ en la Feta 1 de Sil)erli(ht y no e$t5n a%n en NP- Alo$ aCadiremo$ en =utura$ )er$ione$B+ No ten*o =ue cambia" nin(%n c:di(o !ara &ue =uncione con e$to$ controle$, ni $i&uiera la red, LINQ to ?8L, ni el c:di(o de enlace a la ba$e de dato$+ Dna )e6 &ue hemo$ hecho e$to$ cambio$, el c:di(o $e com!ila $in nin(%n !roblema+ !aso -: Dostin* de la aplicaci5n en una )entana #ntonce$ abr' el archi)o Nindo.$1+9aml en el !royecto de e$critorio A&ue e$ la )entana &ue $e car(a !or de=ecto cuando arranca la a!licaci:nB+

3cutali64 el titulo de la )entana a 0Ei(( Ee$/to! *er$ion2 y aument4 el Nidth y el Wei(ht de la )entana+ Lue(o aCad' nue$tro u$er control Pa(e+9aml del !royecto de Sil)erli(ht como el control ra'6 de la )entana+ #$to har5 &ue $ea )i$ible y &ue $e car(ue cuando $e car(ue la )entana+ No ten(o &ue cambiar nin(%n c:di(o de la cla$e Pa(e ni renombrar nada+ ;omo hereda de la cla$e D$er;ontrol !uede ho$tear$e dentro de cual&uier )entana o control NP-+

Lo %ltimo &ue he tenido &ue cambiar una co$illa debido a &ue el $er)idor de la a!i de Ei(( detecta cuando un cliente no e$ un na)e(ador y al(una$ )ece$ le denie(a el acce$o A!robablemente !ara e)itar $cri!t$ autom5tico$ accedan a $u $er)icioB+ #$to lo re$ol)' a tra)4$ de una url de !ro9y A$in cambiar c:di(o, $:lo un cambio de urlB+ !aso /: Ejecuta" la aplicaci5n Xa e$tamo$ li$to$ !ara e7ecutar la a!licaci:n de Nindo.$+ -unciona todo e9actamente i(ual &ue con la )er$i:n de $il)erli(ht:

X cuando $eleccionamo$ un elemento de la li$ta, )emo$ lo$ detalle$:

Way un !ar de di=erencia$ co$m4tica$ entre la )er$i:n del na)e(ador y la de e$critorio+ #$to e$ !or&ue NP- hereda todo$ lo$ e$tilo$ !or de=ecto A=uente$, colore$, $croll bar$, etcB ba$5ndo$e en el tema de e$critorio del $i$tema o!erati)o &ue e$t5 $eleccionado, mientra$ &ue Sil)erli(ht tiene un tema !or de=ecto &ue u$amo$ en todo$ lo$ $i$tema$ o!erati)o$+ Si &ueremo$ &ue la$ )er$ione$ de e$critorio y la .eb $ean el mi$mo !odemo$ con$e(uirlo $iendo e9!l'cito$ en nue$tro$ e$tilo$ y en lo$ tem!late$ de lo$ controle$ < de otra manera la )er$i:n de e$critorio $e ada!tar5 al tema del u$uario+ 2esumen Pronto tendremo$ al(una$ nota$ y $u(erencia$ de buena$ !r5ctica$ a la hora de com!artir c:di(o entre a!licacione$ Sil)erli(ht y NP- m5$ adelante+ ;reo &ue hab4i$ encontrado la$ caracter'$tica$ nece$aria$ !ara crear a!licacione$ Sil)erli(ht y &ue e$ muy $encillo !a$arlo a !royecto$ NP-+ ,ambi4n e$tamo$ traba7ando en &ue haya una mayor com!atibilidad entre e$te ti!o de a!licacione$ !ara &ue !ermitir la reutili6aci:n de c:di(o entre $olucione$, controle$, contenido y c:di(o =5cilmente+

Potrebbero piacerti anche