linq to sql 8

6

Click here to load reader

Upload: jcfarit

Post on 13-Jun-2015

39 views

Category:

Internet


3 download

DESCRIPTION

Ejemplo de consultas en Linq to Sql Parte8

TRANSCRIPT

Page 1: Linq to sql 8

LINQ to SQL (Parte 8 – Ejecutar consultas SQL

personalizadas)

4 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í teneis 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.

En los dos últimos post vismo cómo podemos usar los procedimientos almacenados de nuestra base de datos para

consultar, insertar, actualizar y borrar datos con el modelo de LINQ to SQL.

Una pregunta que me han hecho mucho desde que he escrito estos post es: ¿que pasa si quiero control total sobre las

consultas SQL que usa LINQ to SQL - pero no quiero usar SPROCs para hacerlo? En el post de hoy veremos eso - y

veremos cómo podemos usar expresiones SQL personalizadas para que LINQ to SQL las use en lugar de las que

generaría él.

Uso de expresiones LINQ con LINQ to SQL.

Supongamos que hemos usado el diseñador de LINQ to SQL de VS 2008 para modelar un conjunto de clases a partir

de la base de datos Northwind (esto lo vimos en el segundo post de la serie):

Page 2: Linq to sql 8

En el tercer post vimos cómo podemos usar LINQ con las nuevas características de VB y C# para consultar el modelo

de clases y devolver un conjunto de objetos que representan las filas y columnas de la base de datos.

Por ejemplo, podemos añadir un método a la clase DataContext "GetProductsByCategory" que usa una consulta LINQ

para devolver objetos de Products de la base de datos:

VB:

c#:

Page 3: Linq to sql 8

Una vez definido nuestro método de LINQ, podemos escribir el siguiente código para obtener productos e iterar sobre

ellos:

VB:

Cuando se evalúa la expresión LINQ del método "GetProductsByCategory", el ORM LINQ to SQL ejectuará un SQL

dinámico para obtener los datos de la tabla Product para crear los objetos Product. Podeis usar el Visualizador de

Debug de LINQ to SQL para ver en el debugger cuál es la expresión LINQ que se ejectuará.

Uso de consultas SQL personalizadas con LINQ to SQL

En el ejemplo de arriba no tenemos que escribir ningún código SQL para consultar y obtener objetos Product

fuertemente tipados. LINQ to SQL traduce la expresión LINQ a SQL por nosotros.

¿Pero que pasa si queremos un control total sobre el SQL que se está ejecutando en nuestra base de datos, y no

queremos que LINQ to SQL lo haga por nosotros? Una forma de conseguir esto es usando SPROC como ya vimos en

las partes 6 y 7 de esta serie. La otra forma es usar el método auxiliar "ExecuteQuery" de la clase DataContext y usar

una expresión SQL personalizada que le demos.

Usando el método ExecuteQuery

El método ExecuteQuery toma una expresión SQL como argumento , con un conjunto de parámetros, y la ejecuta

contra la base de datos (incluyendo JOINs personalizados sobre varias tablas.

Page 4: Linq to sql 8

Lo que hace que ExecuteQuery sea tan útil es que nos permite especifiar cómo queremos devolver los valores de la

expresión SQL. Podemos hacer esto pasándole un parámetro tipado al método o usando una versión genérica del

método.

Por ejemplo, podemos cambiar el método GetProductsByCategory() que creamos ántes -con una expresión LINQ- para

que use el método ExecuteQuery para ejectuar un SQL que nosotros le digamos:

VB:

C#:

Ahora podemos llamar al método GetProductsByCategory() de la misma forma que ántes:

De esta manera será nuestra consulta SQL la que se ejecutará contra la base de datos - y no el SQL dinámico que

generaría la expresión LINQ.

SQL personalizado y tracking de objetos para las actualizaciones

Por defecto cuando obtenemos objetos con LINQ to SQL, se hace un tracking sobre los cambios que les hacemos. Si

llamamos al método "SubmitChanges()" guardará los datos de forma transaccional en la base de datos. Vismo esto en

la cuarta parte de esta serie de post.

Una de las característcias del metodo ExecuteQuery() es que participa en este tracking de objetos para actualizar el

modelo. Por ejemplo, podemos escribir el siguiente código para obtener todos los productos de una categoría y rebajar

los precios un 10%:

Page 5: Linq to sql 8

Como dijimos que el tipo de resultado del ExecuteQuery en el método GetProductsByCategory fuese "Product, LINQ

to SQL sabe cómo guardar los cambios. Y cuando llamemos a SubmitChanges los guardará.

SQL personalizado con clases personalizadas.

El método ExecuteQuery nos permite especificar cualquier clase como tipo de resultado de la consulta SQL. La clase

no tiene porqué haberse creado con el diseñador LINQ to SQL, o implementar ninguna interfaz.

Por ejemplo, definimos la clase ProductSummary con un subconjunto de las propiedades de Product (fijáos que hemos

usado la característica de propiedades automáticas):

Podríamos crear otro método en nuestro DataContext llamado GetProductSummariesByCategory() que nos devuelva

objetos de esa clase. Fijáos cómo la siguiente SQL obtiene sólo un subconjunto de Product - El método

ExecuteQuery() se encarga de mapea automáticamente las propiedades a objetos de la clase ProductSumary:

Ahora podemos invocar a este método e iterar sobre los resultados con el siguiente codigo:

SQL personalizadas para inserciones, actualizaciones y borrados.

Además de usar SQL personalizadas para consultar datos, también podemos hacerlas para insertar, actualizar y borrar

datos.

Page 6: Linq to sql 8

Esto lo conseguimos creando los métodos parciales adecuados para cada operacion para la entidad que queramos

cambiar en nuestra clase DataContext. Podemos usar el método ExecuteCommand del DataContext para escribir el

SQL que queramos. Por ejemplo, para sobreescribir el comportamiento de borrado de la clase Product definimos el

siguiente método parcial:

Y si escribimos un código que elimine un producto de la base de datos, LINQ to SQL llamará al método DeleteProduct

- que ejecutará una SQL personalizada en lugar del SQL dinámico que LINQ to SQL usaría:

Resumen

El ORM LINQ to SQL genera y ejectua un SQL dinámico para las consultas, actualizaciones, inserciones y borrados

contra la base de datos.

Para escenarios más avanzados, o en caso donde queramos un control total sobre el SQL que se ejecuta, también

podemos personalizar el ORM para que ejecute SPROCs, o nuestras consultas SQL personalizadas. Esto nos da una

gran flexibilidad a la hora de construir y extender nuestra capa de datos.

En próximos post veremos algunos conceptos de LINQ to SQL como: Herenacia simple de talbas, carga a petición,

concurrencia optimista, y escenarios de N-capas.