linq to sql 3

11

Click here to load reader

Upload: jcfarit

Post on 13-Jun-2015

42 views

Category:

Internet


7 download

DESCRIPTION

Ejemplo de consultas en Linq to Sql Parte3

TRANSCRIPT

Page 1: Linq to sql 3

LINQ to SQL (3ª Parte – Consultando la base de datos)

20 respuestas

El mes pasado empezé una serie de post sobre LINQ to SQL. LINQ to SQL es un framework O/RM (Object

relational mapping) que viene como parte del .NET Framework 3.5, que nos permite modelar de forma sencilla bases

de datos relacionales con clases de .NET. Podemos usar, por tanto, expresiones LINQ tanto para consultar a la base de

datos como para actualizar/inertar/borrar datos.

Aquà tenéis los enlaces a los primero dos post de esta serie:

Usando LINQ to SQL (1ª Parte)

LINQ to SQL (2ª Parte - Definiendo nuestras clases del modelo de datos)

En el post de hoy vamos a ver en más detalle cómo usar el modelo de datos que creamos en la segunda parte, y

veremos cómo usarlo para consultar datos en un proyecto ASP.NET.

Modelo de la base de datos Northwind con LINQ to SQL

En el segundo post de la serie vimos cómo crear un modelo de clases LINQ to SQL usando el diseñador de LINQ to

SQL que viene con VS 2008. Aquà tenéis el modelo que creamos a partir de la base de datos de ejemplo

Northwind:

Obteniendo productos.

Una vez que tenemos definido nuestras clases del modelo de datos, podemos consultar y obtener fácilmente datos de

nuestra base de datos. LINQ to SQL nos permite esto usando la sintáxis de consultas de LINQ sobre la clase

NorthwindDataContext que creamos con el diseñador LINQ to SQL.

Page 2: Linq to sql 3

Por ejemplo, para obtener e iterar sobre una secuencia de objetos Product podemos escribir el siguiente código:

En esta consulta hemos usado la sentencia "where" en nuestra consulta LINQ para devolver aquellos productos de una

categorÃa. Estamos usando el campo/propiedad CategoryID del producto para hacer el filtro.

Una de las cosas que nos aporta LINQ to SQL es que nos da una total flexibilidad en cómo consultar nuestros datos, y

podemos aprovecharnos de las asociaciones que hicimos cuando modelamos las clases de LINQ to SQL para hacer

consultas más naturales y ricas sobre la base de datos. Por ejemplo, podemos modificar el filtro de la consulta por el

CategoryName en lugar de por el CategoryID con la siguiente consulta LINQ:

Fijáos en cómo estamos usando la propiedad "Category" de cada objeto Product para filtrarlos por CategoryName.

Esta propiedad fue creada automáticamente por LINQ to SQL ya que modelamos las clases Category y Product con

una relación "varios a uno" en la base de datos.

Por poner otro ejemplo del uso de las relaciones de nuestro modelo, podrÃamos escribir la siguiente consulta LINQ

para obtener aquellos productos que tengan más de cinco órdenes para ellos:

Fijáos cómo usamos la colección "OrderDetails" que LINQ to SQL creó en cada clase Product (debido a la

relación 1 a varios que modelamos en el diseñador LINQ to SQL).

Visualizando consultas LINQ to SQL en el debugger

Los ORM como LINQ to SQL administran automáticamente la creación y la ejecución del código SQL cuando

realizamos consultas o actualizaciones sobre su modelo de objetos.

Una de los mayores preocupaciones que tienen los desarrolladores sobre los ORMs es "¿pero qué código SQL se

está ejecutando?" Una de las cosas que hace LINQ to SQL es poder ver exáctamente qué código SQL se está

ejecutando cuando ejecutamos nuestra aplicación con el debugger.

Page 3: Linq to sql 3

Con la beta 2 de VS 2008 podemos usar el nuevo plug-in de visualización LINQ to SQL para ver (y testear) cualquier

consulta LINQ to SQL. Simplemente añadimos un breakpoint y pasamos el ratón por encima y hacemos clic en la

lupa para visualizar esa consulta:

ESto nos mostrará un cuadro de diálogo que nos dirá exactamente la SQL que LINQ to SQL usará cuando se

ejecute la consulta para obtener los objetos Product:

Si pulsamos el botón "Execute" de este diálogo nos permitirá evaluar el SQL dentro del debugger y nos mostrará

los resultados de la base de datos:

Obviamente esto hace realmente fácil ver qué lógica de consultas SQL está realizando LINQ to SQL. Fijáos

que podemos sobreescribir la SQL que LINQ to SQL ejecutará si queremos cambiarlo - sin embargo, en el 98% de

los casos creo que os dareis cuenta de que el código SQL que LINQ to SQL ejecuta es realmente bueno.

Enlazando consultas LINQ to SQL a controles ASP.NET

Page 4: Linq to sql 3

Los resultados de las consultas LINQ implementa la interfaz IEnumerable - la cual es una interfaz que los controles de

servidor de ASP.NET soportan para enlazar datos. Lo que implica que podemos enlazar los resultados de cualquier

consulta LINQ, LINQ to SQL, o LINQ to XML a cualquier control ASP.NET.

Por ejemplo, podemos declarar un control <asp:gridview> en una página .aspx de la siguiente forma:

Luego, podemos enlazar los resultados de la consulta LINQ to SQL que escribimos antes:

Esto generará una página como la siguiente:

Restringiendo los resultados de la consulta.

Hasta ahora, cuando evaluamos una consulta de productos, estamos obteniendo por defecto todas las columnas de

datos necesarias para cubrir la entidad de Product.

Por ejemplo, esta consulta para obtener productos:

Page 5: Linq to sql 3

El resultado de esta consulta es:

Normalmente sólo queremos un subconjunto de los datos de cada producto. Podemos usar la nueva caracterÃstica

que LINQ y los compiladores de C# y VB tienen para indicar que sólo queremos un subconjunto de los datos,

modificando la consulta LINQ to SQL de la siguiente forma:

Con esto obtendremos un subconjunto de los datos que se obtienen de la base de datos (como vemos con el visor del

debugger):

Page 6: Linq to sql 3

Lo realmente útil de LINQ to SQL es que podemos aprovecharnos de las asociaciones entre clases de nuestro modelo

de datos cuando restringimos los datos. Esto nos permite expresar consultas útiles y muy eficientes. Por ejemplo, la

siguiente consulta obtiene los ID y los nombres de la entidad Product, el número total de pedidos que hemos hecho

de productos, y los suma al total de pedidos de Productos:

La expresión a la derecha de la propiedad "Revenue" es un ejemplo del uso del método de extensión "Sum" de

LINQ. Toma una expresión Lambda que devuelve el valor de cada pedido de producto como argumento.

LINQ to SQL es listo y es capaz de transformar la expresión LINQ anterior al siguiente SQL cuando es evaluado (con

el visor del debugger):

Page 7: Linq to sql 3

La sentencia SQL anterior hace que los valores NumOrders y Revenue se calculen dentro del servidor SQL, y

devuelve los siguientes valores de la base de datos (realmente rápido):

Podemos enlazar el resultado anterior a nuestro gridview:

Page 8: Linq to sql 3

BTW - en caso de que os lo preguntéis, tenemos intellisense en VS 2008 cuando escribimos estos tipos de

restricciones en las consultas LINQ:

En este ejemplo estamos declarando un tipo anónimo que usa la inicialización de objetos para amoldar y definir la

estructura del resultado. Y seguimos teniendo intellisense en VS 2008, chequeo de compilación y soporte para

refactoring con estos tipos anonimos:

Page 9: Linq to sql 3

Paginando los resultados de la consulta.

Una de las necesidades más comunes en entornos web es la posibilidad de hacer eficientemente la paginanción en

las interfaces de usuario. LINQ tiene dos métodos de extensión que permite hacer esto de forma fácil y eficiente -

los métodos Skip() y Take().

Podemos usar los métodos Skip() y Take() para indicar que sólo queremos devolver 10 objetos producto - desde la

fila que le pasemos como argumento:

Fijáos que no añadimos ni Skipt() ni Take() en la primera consulta - sino que lo hacemos después de la consulta

(cuando lo enlazamos a la fuente de datos del GridView). Muchos me preguntan "¿pero esto no significa que primero

obtiene todos los datos de la base de datos y luego hace la paginación (esto es malo)?" No. La cuestión es que LINQ

usa un modelo de ejecución en diferido, es decir, la consulta no se ejecuta hasta que se itera sobre los resultados.

Uno de los beneficios de este modelo de ejecución en diferido es que nos permite crear consultas en varias lÃneas

de código (lo que mejora la claridad). También nos permite crear las consultas después de otras - lo que nos

permite composiciones más flexibles y reutilización.

Una vez que tenemos el método BindProduct(), podemos escribir el siguiente código en nuestra página para

obtener el Ãndice de inicio de la consulta y hacer que los productos sean paginados y mostrados en el gridview:

Page 10: Linq to sql 3

Esto nos dará una página de productos, filtrada para mostrar aquellos productos que tengan más de cinco pedidos,

mostrando datos calculados dinámicamente, y que son paginables a partir de una cadena de consulta:

Nota: Cuando trabajamos contra SQL 2005, LINQ to SQL usará la función SQL ROW_NUMBER() para crear toda

la lógica de paginación en la base de datos. Esto nos asegura que sólo devolverá las 10 filas de datos que

queremos mostrar en la página:

Esto hace realmente fácil y eficiente navegar por grandes cantidades de datos.

Page 11: Linq to sql 3

Resumen

Hemos visto por encima alguna de las cosas que LINQ to SQL nos ofrece. Para aprender más sobre expresiones

LINQ y las nuevas caracterÃsticas de consultas que traen los compiladores de C# y VB con VS 2008, leed estos post:

Nuevas caracterÃsticas de la nueva versión de C# Orcas

Métodos de extensión.

Expresiones Lambda

Sintaxis de consultas

Tipos anónimos

En el próximo post de esta serie sobre LINQ to SQL veremos cómo podemos añadir lógica de validación a

nuestro modelo de clases de datos, y mostraremos cómo podemos usarlo para encapsular la lógica de negocio que se

ejecutará con cada actualización, inserción o borrado de nuestros datos. Veremos casos más avanzados, cómo

usar el nuevo control <asp:LINQDataSource> para añadir enlaces de datos declarativos a controles ASP.NET,

resolución de errores de concurrencia optimista, y más.