Introduccion a Linq

38
 Usando LINQ to SQL (1ª Parte)  LINQ, LINQ to SQL, Scott Guthrië Add comments may202007  En lo s últimos meses he escrito una serie de po st qu e cu br ían algunas de las características que van a venir con Visual Studio y .NET Framework “Orcas”. Aquí tenéis los enlaces: Propiedades automáticas, inicializadores de objetos e inicializadores de colecciones. Métodos de extensión.  Expresiones Lambda. Sintaxis de consultas.  Tipos Anónimos Las características anteriore s hacen que la consulta de datos sea un concepto de primera clase. Conocemos a este modelo de programación como “LINQ” – que viene de .NET Language Integrated Query. Los desarrolladores pueden usar LINQ con cualquier fuente de datos. Pueden expresar consultas eficientemente en los lenguajes de programación que eligan, opcionalme nte transformar/incrusta r los resultados de las consultas en el formato que quieran, y entonces manipular fácilmente los resultados. Los lenguajes habilitados para LINQ pueden aportar seguridad de tipos y chequeo en tiempo de compilación en las expresiones de consulta, y desarrollar herramientas que aporten intelisense, debugging, y un gran soporte para refactoring cuando escriban código de LINQ. LINQ soporta un modelo de extensibilidad muy rico que facilita la creación de operadores eficientes para fuentes de datos. La versión “Orcas” del .NET Framewor k viene con librerías que habilitan LINQ sobre objetos, XML y bases de datos. ¿Qué es LINQ to SQL? LINQ to SQL es una implementación de O/RM(object relational mapping, mapeador de objetos relacionales) que viene con la versión “Orcas” del .NET Framework, y nos permite modelar bases de datos relacionales con clases de .NET. Podemos consultar bases de datos con LINQ, así como actualizar/añadir/borrar datos de ellas. Modelando bases de datos con LINQ to SQL:

Transcript of Introduccion a Linq

Page 1: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 1/38

 

Usando LINQ to SQL (1ª Parte) LINQ, LINQ to SQL, Scott Guthrië Add comments

may202007

 

En los últimos meses he escrito una serie de post que cubrían algunas de lascaracterísticas que van a venir con Visual Studio y .NET Framework “Orcas”. Aquí tenéis

los enlaces:

• Propiedades automáticas, inicializadores de objetos e inicializadores de

colecciones.

• Métodos de extensión. 

• Expresiones Lambda.

• Sintaxis de consultas. 

• Tipos Anónimos

Las características anteriores hacen que la consulta de datos sea un concepto de primera

clase. Conocemos a este modelo de programación como “LINQ” – que viene de .NET

Language Integrated Query.

Los desarrolladores pueden usar LINQ con cualquier fuente de datos. Pueden expresar 

consultas eficientemente en los lenguajes de programación que

eligan, opcionalmente transformar/incrustar los resultados de las consultas en el formato

que quieran, y entonces manipular fácilmente los resultados. Los lenguajes habilitados

para LINQ pueden aportar seguridad de tipos y chequeo en tiempo de compilación en las

expresiones de consulta, y desarrollar herramientas que aporten intelisense, debugging, y

un gran soporte para refactoring cuando escriban código de LINQ.

LINQ soporta un modelo de extensibilidad muy rico que facilita la creación de operadores

eficientes para fuentes de datos. La versión “Orcas” del .NET Framework viene con

librerías que habilitan LINQ sobre objetos, XML y bases de datos.

¿Qué es LINQ to SQL?

LINQ to SQL es una implementación de O/RM(object relational mapping, mapeador de

objetos relacionales) que viene con la versión “Orcas” del .NET Framework, y nos permite

modelar bases de datos relacionales con clases de .NET. Podemos consultar bases de

datos con LINQ, así como actualizar/añadir/borrar datos de ellas.

Modelando bases de datos con LINQ to SQL:

Page 2: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 2/38

 

Visual Studio “Orcas” viene con un diseñador de LINQ to SQL que nos aporta una forma

fácil de modelar y visualizar una base de datos como un modelo de objeto de LINQ to

SQL. El próximo post cubrirá en más profundidad cómo usar este diseñador (podéis ver 

éste video que hice en Enero para verme construir un modelo LINQ to SQL).

Usando ese diseñador LINQ to SQL puedo crear fácilmente una representación de la base

de datos “Northwind”:

El diseño de arriba define cuatro clases: Product, Category, Order y OrderDetail. Las

propiedades de cada clase mapean las columnas de cada table en la base de datos. Cada

instancia de esa clase representa una fila en las tablas.

Page 3: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 3/38

 

Las flechas entre las cuatro clases de arriba representan las asociaciones/relaciones entre

las diferentes entidades. Son típicamente modeladas como relaciones primary-key/foreign-

key en la base de datos. La dirección de las flechas en el diseñador indican si la relación

es uno-a-uno o uno-a-varios. Se añadiran propiedades fuertemente tipadas a las entidades

basándose en esto. Por ejemplo, la clase Category de arriba tiene una relación de uno-a-

varios con la clase Product. Esto implica que tendrá una propiedad “Categories” que es

una colección de objetos Product con esa categoría. La clase Product entonces tiene una

propiedad “Category” que apunta a una instancia de la clase Category representando la

categoría a la que pertenece el producto.

El panel de la derecha del diseñador LINQ to SQL contiene una lista de procedimientos

almacenados que interactúan con nuestro modelo de base de datos. En el ejemplo dearriba hemos añadido un SPROC (Procedimiento almacenado) “GetProductsByCategory”.

Como entrada recibe un categoryID, y devuelve una secuencia de Product como resultado.

Veremos cómo llamar a este procedimiento almacenado en un ejemplo.

Entendiendo la clase DataContext

Cuando pulsáis el boton “save” del diseñador de LINQ to SQL, Visual Studio generará

clases .NET para representar las entidades y las relaciones de la base de datos que

hemos modelado. Por cada archivo añadido a nuestra solución por el diseñador LINQ to

SQL también se generará una clase DataContext. Esta clase es a traves de la cual

realizaremos las consultas a las entidades de nuestra base de datos. Esta clase tendrá

propiedades que representarán a cada tabla que hemos modelado, así como métodos

para cada procedimiento almacenado que añadamos.

Por ejemplo, aquí tenéis la clase NorthwindDataContext:

Page 4: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 4/38

 

Ejemplos de LINQ to SQL

Una vez que hemos modelado nuestra base de datos con el diseñador de LINQ to SQL,

podemos escribir código fácilmente para trabajar con él. Aquí tenéis unos cuantos

ejemplos que muestran tareas comunes con datos:

1) Consultando Products de la base de datos

El siguiente código usa una consulta LINQ para obtener una secuencia IEnumerable de

objetos Product. Fijáos que este código está consultando a traves de la relación

Product/Category para obtener aquellos productos de la categoría “Beverages”.

C#:

Page 5: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 5/38

 

VB:

2) Actualizando un producto en la base de datos.

El código siguiente muestra cómo obtener un producto de la base de datos, actualizar su

precio, y guardar los cambios en la base de datos:

C#:

VB:

Nota: VB en “Orcas” Beta1 no soporta Lambdas aún. Pero en la Beta2 sí -de forma que el

código anterior se podrá escribir de una forma más concisa.

3) Añadir una nueva categoría y dos nuevos productos en la base de datos.

El siguiente código muestra cómo crear una nueva categoría, y entonces crear dos nuevos

productos y asociarlos a la nueva categoría. Los tres son después guardados en la base

de datos.

Page 6: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 6/38

 

Fijaos como no necesitamos administrar manualmente las relaciones

primarykey/foreignkey. Sólo tenemos que añadir los objetos Product en la colección

“Products” de la categoría, y luego añadir el nuevo objeto Category en la colección de

“Categories” del DataContext, LINQ to SQL sabrá automáticamente crear las PF/FK

necesarias:

C#:

4)Borar productos de la base de datos.

El código siguiente muestra cómo borrar todos los productos Toy de la base de datos:

C#:

VB:

Page 7: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 7/38

 

5) Llamar a un procedimiento almacenado.

El código siguiente muestra cómo obtener entidades de la tabla Product sin usar una

consulta LINQ, sino llamando al procedimiento almacenado “GetProductsByCategory” que

añadimos a nuestro modelo de datos. Fijáos que cuando obtenemos los resultados de la

tabla Product, podemos actualizar/borrarlos y llamar a db.SubmitChanges() para hacer lasmodificaciones en la base de datos.

C#:

VB:

Page 8: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 8/38

 

6) Obtener productos con paginado del lado del servidor 

El código siguiente muestra cómo implementar un paginado eficiente en el lado servidor 

como parte de una consulta LINQ. Usando los operadores Skip() y Take(), sólo

devoleremos 10 filas de la base de datos – a partir de la fila 200.

C#:

VB:

Resúmen:

Page 9: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 9/38

 

LINQ to SQL nos permite modelar la capa de datos de nuestras aplicaciones de una forma

simple y limpia. Una vez que hayamos definido nuestro modelo de datos, podemos realizar 

consultas, inserciones, actualizaciones y borrados sobre ella de forma fácil y eficiente.

Espero que esta introducción os haya abierto el apetito de aprender más. En las próximas

semanas continuaré esta serie de post explorando el LINQ to SQL en más detalle.

Espero que sirva.

Page 10: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 10/38

 

LINQ to SQL (2ª Parte – Definiendo nuestras clasesdel modelo de datos) .NET, ASP .NET, LINQ, LINQ to SQL, Visual Studio Add comments

may302007

 

En la primera parte de la serie de post sobre LINQ to SQL hablé sobre “¿qué es LINQ to

SQL?” y vimos por encima algunos escenarios que permite.

En aquél post pusimos unos cuantos ejemplos de código donde demostrábamos cómo

mejorar la parte de datos usando LINQ to SQL:

• Cómo consultar una base de datos.

• Cómo actualizar filas en una base de datos

• Cómo añadir y relacionar varias filas en una base de datos.

• Cómo eliminar filas de la base de datos.

• Cómo llamar a procedimientos almacenados.

• Cómo obtener datos con paginación en el servidor.

Mejoramos todos estos escenarios usando un modelo de clases de LINQ to SQL como

éste:

Page 11: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 11/38

 

En este segundo post de la serie vamos a ver en más detalle cómo crear el modelo

anterior con LINQ to SQL.

LINQ to SQL, el diseñador de LINQ to SQL, y todas las características que estamos viendosaldrán con la versión de .NET 3.5 y en la release de Visual Studio “Orcas”.

Podéis seguir todos los pasos siguientes descargándo tanto Visual Studio “Orcas” Beta

1 o Visual Web Developer Express “Orcas” Beta 1. Podéis instalar las dos y usarlas sin

ningún problema con Visual Studio 2005.

Crear un nuevo modelo de datos LINQ to SQL

Podemos añadir un modelo de datos de LINQ to SQL a un projecto ASP.NET, Class

Library o Windows, con la nueva opción “Add New Item” seleccionando “LINQ to SQL”:

Page 12: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 12/38

 

Seleccionando “LINQ to SQL” lanzará el diseñador de LINQ to SQL, y nos permitirá

modelar las clases que representen una base de datos relacional. También creará una clas

fuertemente tipada “DataContext” que tendrá las propiedades que representarán cualquier 

tabla que modelemos de la base de datos, así como métodos para cada procedimiento

almacenado que modelemos. Como describimos en la primera parte de esta serie de post,

la clase DataContext es el conducto principal que usaremos tanto para consultar la base

de datos como para guardar los cambios que hagamos.

Aquí tenéis una captura de pantalla de un diseño LINQ to SQL ORM vacío, es lo que

veréis despues de crear un nuevo modelo de datos LINQ to SQL:

Page 13: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 13/38

 

Clases Entidad (Entity)

LINQ to SQL nos permite modelar clases que mapeen una base de datos. Estas clases

son típicamente conocidas como “Clases Entidad” (en ingles “Entity Classes”) y a las

instancias se las conoce como “Entidades” (en ingles “Entities”). Las clases entidadmapean a tablas de una base de datos. Las propiedades de una clase entidad

normalmente mapean las columnas de la tabla. Cada instancia de una clase entidad

representa a una fila de una tabla de la base de datos.

Las clases entidad definidas por LINQ to SQL no tienen que derivar de una clase base

específica, lo que significa que pueden heredar de cualquier objeto que queramos. Todas

las clases creadas por el diseñador de LINQ to SQL se definen como “clases parciales” –

con lo que podemos, opcionalmente, añadir propiedades adicionales, métodos y eventos.

A diferencia de la característica de DataSet/TableAdapter que aporta VS 2005, cuando

usamos el diseñador de LINQ to SQL no tenemos que especificar qué consultas SQL se

tiene que usar cuando creamos el modelo de datos y la capa de acceso.

En lugar de eso, nos centramos en definir las clases entidad, cómo se mapean con la base

de datos, y las relaciones entre ellas. La implementación del ORM de LINQ to SQL se

encargará de generar la lógica de ejecución SQL por nosotros en tiempo de ejecución para

que podamos interactuar y usar las entitades de datos. Podemos usar sintaxis de

Page 14: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 14/38

 

consultas LINQ para indicar cómo consultar nuestro modelo de datos de forma

fuertemente tipada.

Crear clases entidad de la base de datos.

Si ya tenemos un esquema de base de datos definido, podemos usarlo para crear clases

entidad LINQ to SQL.

La forma más sencilla de conseguirlo es abrir la base de datos desde el “Server Explorer”

de Visual Studio, seleccionar las tablas y vistas (Views) que queramos modelar, y

arrastrarlas al diseñador LINQ to SQL:

Cuando añadimos estas dos tablas (Categories y Products) y una vista (Invoices) de la

base de datos “Northwind” al diseñador de LINQ to SQL, tendremos las siguientes clases

entidad creadas a partir del esquema de la base de datos:

Page 15: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 15/38

 

Usando estas clases, podemos ejecutar todos los ejemplos de código (excepto el de

procedimientos almacenados) que vimos en la primera parte de esta serie sobre LINQ to

SQL. No tenemos que añadir ningún código adicional o configuración para habilitar los

escenarios de consulta, inserción, actualización, borrado, y paginación en el servidor.

Nombrado y pluralización

Una de las cosas de las que os daréis cuenta usanto el diseñador de LINQ to SQL es que

automáticamente “pluraliza” los nombres de las tablas y columnas cuando crea las clases

entidad basádas en el esquema de la base de datos. Por ejemplo: la tabla “Products” del

ejemplo se resuelve en una clase “Product”, y la tabla “Categories” se resuelve en la clase

“Category”. Este nombrado de clases hace que vuestro modelo sea más consistente con

las convenciones de nomenclatura de .NET, y encuentro bastante útil que el diseñador haga esto por mi (especialmente cuando añadimos muchas tablas a nuestro modelo).

Si no os gusta el nombre de una clase o propiedad que el diseñador ha generado, siempre

podréis cambiarlo por el que queráis. Podéis hacerlo editanto el nombre de la

entidad/propiedad en el mismo diseñador o cambiarlo en la rejilla de propiedades:

Page 16: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 16/38

 

Esta habilidad de nombrado de entidades/propiedades/asociaciones es muy útil en un gran

número de casos. En particular:

1) Cuando cambie el nombre de una tabla/columna de vuestra base de datos. Como

vuestras entidades tendrán nombres diferentes, podéis decidir actualizar las reglas de

mapeado y no el código de vuestra aplicación o las consultas para usar esas nuevas

tablas/columnas.

2) Cuando en el esquema de la base de datos tengais nombres que no son “limpios”. Por 

ejemplo, en lugar de usar “au_lname” y “au_fname” para los nombres de las propiedades

en una clase entidad, podéis usar los nombres de “LastName” y “FirstName” en vuestras

clases entidad y programar con esos nombres, en vez de cambiarlo en la base de datos.

Relaciones

Cuando arrastremos objetos del “server explorer” al diseñador “LINQ to SQL”, Visual

Studio comprobará las relaciones de clave primaria y ajenas de los objetos, y basándose

en ellas creará relaciones por defecto entre las diferentes clases entidad que genere. Por 

ejemplo, cuando añadimos las tablas Products y Categories de la base de datos

NorthWind al diseñador LINQ to SQL podemos ver que se ha deducido una relación de

uno a n entre ellas (esto se indica con la felcha del navegador):

Page 17: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 17/38

 

Esta relación hará que la clase entidad Product tenga una propiedad llamada “Category”

que los desarrolladores usarán para acceder a la entidad Category para un Product dado.

También hará que la clase Category tenga una colección de “Products” que permitirá a los

desarrolladores obtener todos los productos de una Category.

Si no nos gusta cómo el diseñador a nombrado a la relación, siempre podrémos cambiarlo.

Sólo hay que hacer clic en la felcha en el diseñador, ver las propiedades y cambiar el

nombre.

Retrasar la carga

LINQ to SQL permite a los desarrolladores especificar si las propiedades de las entidadesdeben precargarse o retrasarse hasta el primer acceso. Podemos personalizar las reglas

Page 18: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 18/38

 

de precarga/retraso para las propiedades de las entidades seleccionando cualquier 

propiedad o asociación en el diseñador, y en las propiedades poner la propiedad “Delay

Loaded” a true o false.

Por poner un ejemplo, imaginemos la clase entidad “Category” del modelo anterior. La

tabla “Categories” de la base de datos “NorthWind” tiene una columna “Picture” que

contiene una imagen (potencialmente grande) para cada categoría, y sólo queremos esa

imagen cuando vaya a usarla (y no cuando esté haciendo una consulta para obtener los

nombres de las categorías en una lista).

Podríamos configurar la propiedad Picture para que se retrase su carga seleccionandola

en el diseñador de LINQ to SQL y en las propiedades poner “Delay Loaded” a true:

Nota: Además de configurar el significado de la precarga/retraso de las entidades,

podemos sobreescribirlo vía código cuando hagamos consultas LINQ en las clases entidad

(lo veremos en el siguiente post de esta serie).

Usando procedimientos almacenados.

Page 19: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 19/38

 

LINQ to SQL nos permite modelar procedimientos almacenados como métodos de nuestra

clase DataContext. Por ejemplo, supongamos que hemos definido un procedimiento

almacenado simple para obtener la información de un producto de un categoryID:

Podemos usar el server explorer de Visual Studio y arrastrar este procedimiento

almacenado al diseñador de LINQ to SQL para obtener un método fuertemente tipado que

invocará a este procedimiento almacenado. Si lo arrastramos encima de la entidad

“Product” en el diseñador, el diseñador declarará que el procedimiento almacenado

devuelve un IEnumerable<Product>:

Podemos usar tanto una consulta SQL (que generará una consulta SQL adhoc) o invocar 

el procedimiento almacenado añadido para obtener las entidades product de la base de

datos:

Page 20: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 20/38

 

Usar procedimientos almacenados para actualizar/borrar/insertar datos.

Por defecto LINQ to SQL creará automáticamente expresiones SQL apropiadas para

cuando tengamos que insertar/actualizar/borrar entidades. Por ejemplo, si escribimos el

siguiente código LINQ to SQL para actualizar algunos valores en una instancia de la

entidad “Product”:

LINQ to SQL creará y ejecutará una sentencia “UPDATE” apropiada para cuando

aceptemos los cambios (Veremos esto en más profundidad en otros post).

Page 21: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 21/38

 

Podemos definir procedimientos almacenados personalizados para INSERT, UPDATE,

DELETE. Para configurar esto, hacemos clic en una entidad del diseñador LINQ to SQL y

en las propiedades de Delete/Insert/Update, en el botón “…”, y ponemos un procedimiento

almacenado que ya hayamos definido.

Lo curioso es que el cambio de estas propiedades se está realizando en la capa de mapeo

de LINQ to SQL – lo que implica que la actualización del código que vimos ántes sigue

funcionando sin tener que hacer ninguna modificación. Con esto libramos a los

desarrolladores de que si cambiamos el modelo de datos LINQ to SQL, no tienen que tocar 

ningún código para que sigua funcionando si deciden poner un procedimiento almacenado

personalizado.

Resumen

LINQ to SQL provee una forma limpia de modelar las capas de datos de nuestras

aplicaciones. Una vez que tengamos nuestro modelado de datos, podemos realizar de

forma eficiente consultas, inserciones, actualizaciones, y borrados sobre él.

Con el diseñador de LINQ to SQL que viene en Visual Studio y en Visual Web Developer 

Express podemos crear y administrar nuestros modelso de datos para LINQ to SQL

extremadamente rápido. El diseñador LINQ to SQL también permite una gran flexibilidad

Page 22: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 22/38

 

que nos permite personalizar el comportamiento por defecto y sobreescribir/extender el

sistema para que se adapte a nuestras necesidades.

En próximos post usaremos este modelo que hemos creado para ver en más detalle los

procesos de consulta, inserciones, actualizaciones y borrados. En estos post también

veremos cómo añadir validaciones negocio/datos personalizadas a las entidades que

hemos diseñado.

Mike Taulty tiene una gran cantidad de videos sobre LINQ to SQL aquí, os recomiendo que

los veáis. Así tenéis una forma de aprender viendo cómo se usa LINQ to SQL.

Page 23: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 23/38

 

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

.NET, ASP .NET, LINQ, LINQ to SQL, Scott Guthrië Add comments

 jun302007

 

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 Framework3.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 quecreamos 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:

Page 24: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 24/38

 

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.

Por ejemplo, para obtener e iterar sobre una secuencia de objetos Product podemos

escribir el siguiente código:

Page 25: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 25/38

 

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.

Page 26: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 26/38

 

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 cuandoejecutamos nuestra aplicación con el debugger.

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:

Page 27: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 27/38

 

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.

Page 28: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 28/38

 

Enlazando consultas LINQ to SQL a controles ASP.NET

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:

Page 29: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 29/38

 

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:

El resultado de esta consulta es:

Page 30: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 30/38

 

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 31: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 31/38

 

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 32: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 32/38

 

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 33: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 33/38

 

BTW Рen caso de que os lo pregunt̩is, tenemos intellisense en VS 2008 cuando

escribimos estos tipos de restricciones en las consultas LINQ:

Page 35: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 35/38

 

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:

Page 36: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 36/38

 

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:

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:

Page 37: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 37/38

 

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:

Page 38: Introduccion a Linq

5/13/2018 Introduccion a Linq - slidepdf.com

http://slidepdf.com/reader/full/introduccion-a-linq-55a753b8e092f 38/38

 

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

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.