linq to sql 9

7

Click here to load reader

Upload: jcfarit

Post on 13-Jun-2015

41 views

Category:

Internet


2 download

DESCRIPTION

Ejemplo de consultas en Linq to Sql Parte9 Ultima

TRANSCRIPT

Page 1: Linq to sql 9

LINQ to SQL (Parte 9 – Uso de expresiones LINQ

personalizadas con el control )

13 respuestas

En las últimas semanas he escrito una serie de post sobre LINQ to SQL. LINQ to SQL es un ORM que viene con .NET

3.5, y nos permite modelar bases de datos relacionales en clases. Podemos usar expresiones LINQ para consultar la

base de datos y también para actualizar, insertar y borrar datos.

Aquí tenéis los enlaces a los diferentes post de la serie:

Parte 1: Introducción a LINQ to SQL

Parte 2: Definiendo 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 el ASP:LinqDatSource

Parte 6: Obtener datos con procedimientos almacenados.

Parte 7: Actualizando la base de datos con procedimientos almacenados.

Parte 8: Ejecutar consultas SQL personalizadas.

En la quinta parte vimos el control <asp:LinqDataSource> de .NET 3.5 y hablamos sbre cómo podemos enlazar

controles de ASP.NET a LINQ to SQL. También vimos cómo usarlo con el control <asp:ListView> (El control

asp:ListView (Parte 1 - Creación de una página de listado de productos con una CSS limpia))

En ambos artículos las consultas que hacíamos eran relativamente sencillas (la clausula where se ejecutaba sobre una

tabla simple). En el post de hoy veremos cómo usar toda la potecia de las consultas de LINQ con el control

LinqDataSource, y veremos cómo usar cualquier expresion LINQ to SQL con él.

Pequeña recapitulación: <asp:LinqDataSource> con una sentencia Where.

En estos dos post vimos cómo usar el filtro del control LinqDatasource para declarar un filtro en un modelo LINQ to

SQL.

Por ejemplo, supongamos que hemos creado un modelo LINQ to SQL de la base de datos Northwind (que ya vimos en

la segunda parte de esta serie), podríamos declarar un control <asp:LinqDataSource> en la página con un filtro

<where> que devuelve aquellos productos de una categoría dada. (especificada a partir del valor "categoryid").

Luego, podemos enlazar un <asp:gridView> a este datasource y habilitar la paginación, edición y ordenación.:

Page 2: Linq to sql 9

Cuando ejecutamos la página anterior tendremos un GridView que soportará automáticamente la ordenación,

paginación y edición sobre el modelo de Produt:

Usando los parámetros del <where> de esta forma funciona muy bien en escenarios típicos. Pero ¿qué pasa si que el

filtrado de Product sea más complejo? Por ejemplo, ¿Si sólo queremos mostrar los productos suministrados por un

conjunto dinámico de paises?

Uso del evento Selecting del <asp:LinqDataSource>

En consultas personalizadas podemos implementar un manejador de eventos para el evento "Selecting" en el control

<asp:LinqDataSource>. Con este manejador podemos escribir el código que queramos para obtener los datos. Esto lo

podemos hacer con una expresión LINQ to SQL, o llamar a un procedimiento almacenado o usar una expresión SQL

personalizada. Una vez que obtenemos la secuencia de datos, todo lo que tenemos que hacer es asignar la propiedad

"Result" al objeto LinqDataSourceSelectEventArgs. El <asp:LinqDataSource> usará esta secuencia como los datos con

los que trabajará.

Por ejemplo, aquí tenéis una consulta LINQ to SQL que obtiene aquellos productos de los proveedores de un conjunto

de países:

VB:

Page 3: Linq to sql 9

C#:

Nota: No tenemos que escribir la consulta en el código del manejador. Una solución más limpia sería encapsularla en

un método de ayuda al que podríamos llamar desde el propio manejador. Esto lo vimos en la parte 8 de esta serie

(usando el método GetProductsByCategory).

Ahora, cuando ejecutemos la página usando este manejador, sólo obtendremos los productos de los proveedores de

ciertos países:

Page 4: Linq to sql 9

Una de las cosas más interesantes es que la paginación y la ordenación siguen funcionando en nuestro GridView -

aunque estemos usando el evento Selecting. Esta lógica de paginación y ordenación ocurre en la base de datos - es

decir, sólo devolvemos los 10 productos de la base de datos que necesitamos para el índice actual del GridView

(supereficiente).

Os estaréis preguntando - ¿cómo es posible que tengamos una paginación y ordenación eficiente incluso cuando lo

hacemos con un evento personalizado?. La razón es que LINQ usa el modelo de ejecución en diferido - es decir, la

consulta no se ejecuta hasta que intentamos iterar sobre los resultados. Uno de los beneficios de este modelo es que nos

permite componer consultas con otras consultas, y añadirles "comportamiento". Podéis leer más sobre esto en la tercera

parte de la serie LINQ to SQL.

En nuestro evento "Selecting" estamos declarando una consulta LINQ personalizada que queremos ejecutar y luego se

la asignamos a la propiedad "e.Result". Pero aún no la hemos ejecutado (ya que no hemos iterado sobre los resultados

o llamado a los métodos ToArray() o ToList()). El LINQDataSource es capaz de añadir automáticamente los

operadores Skip() y Take() al aconsulta, así como aplicarle una expresión "orderby" -- siendo todos estos valores

calculados automáticamente a partir del índice de página y las preferencias de ordenación del GridView. Sólo entonces

el LINQDataSource ejecuta la expresión LINQ y obtiene los datos. LINQ to SQL se encarga de que la lógica de

ordenación y paginado se haga en la base de datos - y que sólo se devuelvan 10 filas de productos.

Fijáos cómo podemos seguir usando el GridView para editar y borrar datos, incluso cuando usamos el evento

"Selecting" del LINQDataSource:

Page 5: Linq to sql 9

El soporte de edicion/borrado funcionará mientras que el evento Selecting asigne la secuencia de resultados a la

propiedad Result y sean objetos entidad (por ejemplo: una secuencia de Product, Supplier, Category, Order, etc). El

LinqDataSource administrará los casos en el que los controles hagan actualizaciones sobre ellos.

Para leer mas sobre cómo funcionan las actualizaciones con LINQ to SQL, leed la parte cuatro de esta serie, y luego la

parte quinta para ver las Updates en accción.

Realizano proyecciones de consultas personalizadas con el evento Selecting.

Una de las características más poderosas de LINQ es la habilidad de "formar" o "proyectar" datos. Podemos hacer esto

en una expresión LINQ to SQL para indicar que queremos obtener sólo un subconjunto de valores de una entidad, y/o

calcular nuevos valores dinámicamente al vuelo con expresiones personalizadas que definamos. Para leer más sobre

esto leed la tercera parte de la serie.

Por ejemplo, podemos modificar el evento "Selecting" para calcular un GridView para que muestre un subconjunto de

información de Product. En el grid queremo mostrar el ProductID, ProductName, Product UnitPrice, el número de

pedidos de ese producto, y el total de pedidos de ese producto. Podemos calcular estos dos últimos campos con la

siguiente expresión LINQ:

VB:

Page 6: Linq to sql 9

C#:

Nota: El método Sum para calcular el Revenue es un ejemplo de un método de extensión. La función es una expresión

lambda. El tipo de resultados creados de la consulta LINQ es un tipo anónimo - ya que el tipo es inferido de la

consulta. Métodos de extensión, expresiones Lambda, y los tipos anónimos son nuevas características de VB y C# en

VS 2008.

El resultado de esta expresión LINQ cuando lo enlazamos al GridView es el siguiente:

Fijaos que la paginación y la ordenación sigue funcionando en el GridView - aunque estemos usando una proyección

de LINQ para los datos.

Page 7: Linq to sql 9

Una característica que no funcionará con las proyecciones es el soporte para la edición. Esto es debido a que estamos

haciendo una proyección personalizada en el método Selecting, y el LINQDataSource no tiene forma de saber cómo

actualizar la entidad. Si queremos añadir soporte para la edición en este caso, tendremos que crear un control

ObjectDataSource (al que le pondremos un método Update personalizado para contorlarlos), o hacer que el usuario

navegue a una nueva página para hacer la actualización - y mostrar un DetailsView o FormView enlazado a la entidad

Producto para la edición (y no intentar hacerlo en el grid).

Resumen

Podemos realizar consultas personalizadas sobre el modelo LINQ to SQL usando el soporte integrado de filtrado del

LINQDataSource.

Para habilitar opiciones de filtrado más avanzadas, usaremos el método Selecting del LINQDataSource. Esto no

permitirá crear la lógica que queramos para obtener y filtrar datos LINQ to SQL. Podemos llamar a métodos para

obtener los datos, usar Expresiones LINQ, llamar a procedimientos almacenados o invocar una expresión SQL

personalizada para hacer esto.