Sei sulla pagina 1di 16

23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .

NET

LINQ to SQL (Parte 6 Obtener datos con


procedimientos almacenados)
En las ltimas semanas he escrito una serie de post sobre LINQ to SQL. Es un ORM integrado en .NET 3.5, y
nos permite modelar bases de datos relacionales con clases de .NET. Podemos usar expresiones LINQ para
consultar a la base de datos, actualiazarla, insertar y borrar datos.

Aqu tenis los enlaces a los otros post:

Parte 1: Introduccin a LINQ to SQL


Parte 2: De niendo el modelo de datos.
Parte 3: Consultando la base de datos
Parte 4: Actualizando la base de datos.
Parte 5: Enlazar controles de interfaz de usuario con elASP:LinqDatSource

En estos posts vimos cmo usar expresiones LINQ para obtener programticamente datos de la base de
datos.

En el post de hoy veremos cmo podemos usar los procedimientos almacenados (SPROCs) y las funciones
de nidas por el usuario (UDFs) con nuestro modelo LINQ to SQL. El post de hoy veremos el caso de los
SPROCs para consultar y obtener datos de la base de datos. En el siguiente post de esta serie veremos
cmo actualizar/insertar/borrar datos con SPROCs.

SPROC o no SPROC? Esa es la cuestin

La pregunta sobre cuando usar el SQL dinmico generado por un ORM en lugar de procedimientos
almacenados creando una capa de datos es causa de debates muy acalorados entre desarrolladores,
arquitectos y DBAs. Mucha gente ms lista que yo ha escrito sobre esto, as que no me decantar ni por un
lado ni por otro.

LINQ to SQL es muy exible, y puede usare para crear un modelo de datos cuyos objetos sean
independientes del esquema de la base de datos, y puede encapsular lgica de negocio y reglas de
validacin que funcionan tanto si se usa SQL generado dinmicamente o a travs de SPROCs.

En el tercer post de esta serie, hablamos sobre cmo podemos escribirexpresiones LINQ contra el modelo
de LINQ to SQL como el siguiente cdigo:

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 1/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Cuando escribimos expresiones LINQ como esta, LINQ to SQL ejecutar el SQL dinmico necesario para
obtener los objetos de Product que cumplan las restricciones.

Como aprenderemos en este post, tambin podemos mapear SPROCs en la base de datos con la clase
DataContext generada por LINQ to SQL, que nos permitir obtener los mismo objetos de Product llamando
a un procedimiento almacenado:

Esta habilidad de poder usar tanto SQL dinmico como SPROCs con una capa de datos limpia es muy til y
nos permite una gran exibilidad en nuestros proyectos.

Pasos para mapear y llamar a SPROC con LINQ to SQL

En el segundo post de la serie vimos cmo usar el diseador LINQ to SQL para crear el siguiente modelo de
clases:
http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 2/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Fijaos en las dos partes del diseador. La de la izquierda nos permite de nir el modelo de datos que
mapeara nuestra base de datos. El de la derecha nos permite mapear SPROCs (y UDFs) en nuestro objeto
DataContext, que podemos usar en lugar del SQL dinmico para trabajar con los objetos de nuestro
modelo de datos.

Cmo mapear un SPROC en un DataContext de LINQ to SQL

Para mapear SPROCs en la clase DataContext, vamos primero al explorador de servidores de VS 2008 y
miramos a los SPROCs de nuestra base de datos:

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 3/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Haciendo doble clic en cualquier SPROC se abrir para edicin y podremos ver el cdigo. Por ejemplo, aqu
tenis el SPROC "CustOrderHist" de la base de datos Northwind:

Para mapearlo en nuestra clase DataContext, lo arrastarmos y soltamos desde el explorador de servidores
al diseador de LINQ to SQL. Automticamente se crear un nuevo mtodo en la clase DataContext:

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 4/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Por defecto el nombre del nuevo mtodo en la clase DataContext ser el mismo que el del SPROC, y el tipo
de datos devueltos se crear automticamente con el siguiente patron: "[NombredelSPROC]Result". Por
ejemplo: el SPROC de arriba devolver una secuencia de objetos del tipo "CustOrderHistResult". Podemos
cambiar el nombre del mtodo seleccionndolo en el diseador y cambiarlo en la ventana de propiedades.

Como llamar a un nuevo SPROC mapeado.

Una vez que hemos seguido los pasos para mapear el SPROC en la clase DataContext, es muy fcil de usar.
Todo lo que tenemos que hacer es llamarlo para obtener los resultados fuertemente tipados:

En VB:

En C#:

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 5/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Adems de poder hacer un bucle sobre los resultados, tambin podemos enlazar los resultados con
cualquier control para mostrarlos. Por ejemplo, el siguiente cdigo enlaza los resultados del SPROC a un
control <asp:gridview>

Con lo que mostramos la historia de productos de un cliente:

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 6/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Mapeando los tipos resultado de los SPROC del modelo de datos

En el SPROC "CustOrderHist" devolva una secuencia de objetos con dos columnas: el nombre del producto
y el numero total de pedidos que el cliente ha hecho de ese producto. El diseador LINQ to SQL de ni la
clase "CustOrderHistResult" para representar los resultados.

Tambin podemos decidir mapear los resultados del SPROC a una clase de nuestro modelo de datos (por
ejemplo: a una entidad Product o Order).

Por ejemplo, tenemos el SPROC "GetProductsByCategory" en nuestra base de datos que devuelve la
siguiente informacin:

Como ntes podemos crear un mtodo "GetProductsByCategory" en la clase DataContext que llama a este
SPROC arrastrndolo al diseador de LINQ to SQL. Ms que simplemente arrastrar el SPROC al diseador,
lo arrastraremos encima de la clase "Product":

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 7/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Con esto, el mtodo "GetProductsByCategory" devolver una secuencia de objetos "Product":

LINQ to SQL seguir los cambios hechos a los objetos que se devuelvan como si fuesen objetos Products
obtenidos a partir de expresiones LINQ. Cuando llamemos al mtodo "SubmitChanges()" todos los cambios
hechos a esos objetos se guardarn en la base de datos.

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 8/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Por ejemplo, con el siguiente cdigo obtenemos y cambiamos el precio de todos los productos de una
categora aumentndolo en un 90 %:

Para entender cmo funciona el mtodo SubmitChanges() y el seguimiento que se hace de los cambios, y
ver cmo podemos aadir lgica de negocio a nuestro modelo de datos leed el cuarto post de esta serie.

En el prximo post de esta serie veremos tambin cmo cambiar el SQL generado cuando
insertamos/actualizamos/borramos datos con SPROCs personalizados. Lo bueno de todo esto es que el
cdigo anterior no habr que cambiarlo si hemos con gurado la clase DataContext para que use SPROCs
para las actualizaciones -

Manejando resultados mltiples desde SPROCs

Cuando un procedimiento almacenado puede devolver varios tipos de datos, el tipo de resultado del
SPROC en la clase DataContext no puede ser fuertemente tipado. Por ejemplo, imaginemos el siguiente
SPROC que puede devolver un producto o un pedido dependiendo del parmetro de entrada:

LINQ to SQL permite crear mtodos auxiliares para devolver Product o Order aadiendo una clase parcial
"NorthwindDataContext" al proyecto que de na un mtodo (que en este caso llamaremos
"VariablesShapeSample") que invoca al SPROC y devuelve un objeto IMultipleResult:

VB:

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 9/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

C#:

Una vez que aadimos este mtodo al proyecto podemos llamarlo y convetir los resultados tanto a una
secuencia de Product como de Order:

VB:

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 10/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

C#:

Soporte de funciones de nidas por el usuario (UDFs)

Adems de SPROCS, LINQ to SQL tambin soporta tanto funciones de usuario de valores y de tablas de
valores (UDFs). Una vez que aadimos un mtodo a la clase DataContext, podemos usar estasfunciones en
nuestras consultas LINQ.

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 11/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Por ejemplo, veamos la funcin simple "MyUpperFunction":

Podemos arrastrar y soltar desde el explorador de servidores aldiseador deLINQ to SQL para aadirlo
como un mtodo a nuestro DataContext:

Luego podemos usar esta funcin UDF en expresiones LINQ cuando escribimosconsultas contra nuestro
modeloLINQ to SQL:

VB:

C#:

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 12/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Si usamos el visualizador de debug de LINQ to SQLdel que ya hablamos aqu, podemos ver cmo LINQ to
SQL transforma la expresin anterior en una SQL que ejecutar el UDF en la base de datos en tiempo de
ejecucin:

Resumen

LINQ to SQL soporta poder usar procedimientos almacenados y UDFs contra la base de datos y los integra
en nuestro modelo de datos. En este post hemos visto cmo podemos usar SPROCs para obtener datos y
pasarlo entre nuestras clases del modelo. En el prximo post veremos cmo podemos usar SPROCS para
sobreescribir la lgica de actualizacin/insercin/borrado cuando llamamos a SubmitChanges() en el
DataContext para guardar los cambios.

Espero que sirva.

Scott.

Traducido por: Juan Mara La Ramos. Microsoft Student Partner.

toH tlhIngan Hol DajatlhlaH e DaneHa?

Comparte esto:

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 13/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

Facebook 12 Twitter LinkedIn Ms

Esta entrada fue publicada en .NET, ASP .NET, LINQ, LINQ to SQL, Scott Guthri, SQL el 17 Agosto, 2007
[http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/] .

9 pensamientos en LINQ to SQL (Parte 6 Obtener datos con procedimientos


almacenados)

Pingback: LINQ to SQL (Parte 9 - Uso de expresiones LINQ personalizadas con el control ) Thinking in .NET

Pingback: LINQ. que es y como usuarlo. Alexander Jimnez

Linda
8 Septiembre, 2008 en 15:31

hola, tengo un problema porque requiero ejecutar un sp, que no esta ligado a una tabla de nida sino
variable, el cdigo del sp es asi:

var=select +@nombrecampo+ from + @nombretabla

exec var

el sp me regresa la consulta correcta pero no se como puedo implementarlo en c Sharp dado que siempre
la relacin del resultado se identi ca con alguna tabla especi ca.

Podrias ayudarme?
Gracias

Vio
8 Septiembre, 2008 en 20:50

Hola Linda:

Desde C# no puedes llamar directamente a un procedimiento almacenado en una base de datos, para
ello debes usar las libreras de ADO.NET o para facilitarte el trabajo LINQ to SQL.
El procedimiento almacenado debe existir en la base de datos que tengas montada. @nombretabla debe

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 14/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

ser un parmetro que le pases al procedimiento.


Si te re eres a escribir un procedimiento almacenado en c# psate por aqu: http://msdn.microsoft.com/es-
es/library/ms255336%28VS.80%29.aspx

Espero que te sirva.

ING. GARCIA
27 Enero, 2010 en 15:11

Con esta nueva tecnologia linq to sql o linq to entities son necesarios los procedimientos almacenados, o
cual es la mejor opcion hacer las consultas dinamicamente o usar procedimientos almacenados.

Gracias.

L.M.Santin
23 Julio, 2010 en 3:02

Hola:

Cmo hacer en el caso que un SP tiene 3 SELECT?

-El primer SELECT devuelve los detalles del cliente


-El segundo SELECT devuelve las tiendas donde tiene contrato
-El tercer SELECT devuelve las tiendas con las que NO tiene contrato.

Como quedaria de nida la funcion en la partial class del Datacontext y la clase para el resultado?

L.M.Santin
23 Julio, 2010 en 9:58

La respuesta a mi pregunta la encontr en este articulo http://msdn.microsoft.com/en-


us/library/bb399344.aspx

Vale la pena aclarar que los tipos MultipleResultTypesSequentiallyResult1y


MultipleResultTypesSequentiallyResult2 deben ser declarados en la clase parcial del Datacontext en el O/R

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 15/16
23/8/2017 LINQ to SQL (Parte 6 Obtener datos con procedimientos almacenados) | Speaking in .NET

designer, no en el codigo auto generado.


Para declararlos de debe seguir las clases del codigo auto-generado como patron

Henry Wong
23 Febrero, 2011 en 14:09

Si deseas realizar un mini sistema de ventas con C# usando procedimientos almacenados en una base de
datos SQL Server 2008 y aplicando el modelo de programacion en capas puedes visitar los siguiente
enlaces

http://hwongu.blogspot.com/2011/02/c-aplicacion-de-escritorio-sistemas-de.html
http://hwongu.blogspot.com/2011/02/c-aplicacion-de-escritorio-sistemas-de_22.html

Saludos

Cristina
9 Mayo, 2011 en 10:07

hola, tengo hecho un crystalreportviewer, conectandome a la bd con linq to sql. ten el data set le tengo
creada una select y mostrando los campos ltrados. bien ahora quiero poder ordenarlos. cuando le pongo
a esa consulta el order by, y le doy a generar consulta me la crea bien, lo que creo que el problema lo tiene
el crystalreportviewer, porque ahi se muestra siempre de la misma forma, y no se ordena por la columna
que yo le muestro

Los comentarios estn cerrados.

http://speakingin.net/2007/08/17/linq-to-sql-parte-6-obtener-datos-con-procedimientos-almacenados/ 16/16

Potrebbero piacerti anche