Usando LINQ to SQL (1ª Parte)

En los últimos meses he escrito una serie de post que cubrían algunas de las característcias que van a venir con Visual Studio y .NET Framework "Orcas". Aquí tenéis los enlaces:

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 el 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:

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 este 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.

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 de arriba 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:

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#:

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.

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:

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 las modificaciones en la base de datos.

C#:

VB:

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:

Resumen:

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.

Scott.

Traducido por: Juan María Laó Ramos. Microsoft Student Partner

43 pensamientos en “Usando LINQ to SQL (1ª Parte)

  1. Pingback: LINQ to SQL (2ª Parte - Definiendo nuestras clases del modelo de datos) « Thinking in .NET

  2. Pingback: LINQ to SQL (3ª Parte - Consultando la base de datos) « Thinking in .NET

  3. Pingback: LINQ to SQL (5ª Parte - Enlazar controles de interfaz de usuario con el ASP:LinqDatSource « Thinking in .NET

  4. Pingback: LINQ to SQL « Un dia duro

  5. Pingback: Serie de Post sobre LINQ to SQL Server « Alexander Jiménez

  6. Pingback: Visor de Debugging de LINQ to SQL « Thinking in .NET

  7. Pingback: LINQ to SQL (Parte 6 - Obtener datos con procedimientos almacenados) « Thinking in .NET

  8. Pingback: LINQ to SLQ (Parte 7 - Actualizando la base de datos con procedimientos almacenados) « Thinking in .NET

  9. Pingback: LINQ to SQL (Parte 8 - Ejecutar consultas SQL personalizadas) « Thinking in .NET

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

  11. Pingback: LINQ. que es y como usuarlo. « Alexander Jiménez

  12. Pingback: Nuevo soporte para datos dinámicos en ASP.NET « Thinking in .NET

  13. José Cardaropoli

    Hola !!

    Doy mis primeros pasos en .Net programando windows forms con C#, he notado que Linq es una poderosa herramineta que tiene algunos “detalles sin resolver”, en un principio lo adjudique a mi falta de conocimiento, pero luego de leer algunos articulos en la red, veo esta cosas que siento como “debilidades”.
    1. No poder abrir más de un datacontext, no poder “desattachar” (estoy usando VS2008) y tener que utilizar una instancia pública.

    2. Problema con el refresco en los binding de datos en controles.

    Igualmente veo en Linq to Sql (aunque he leido que MS no lo recominenda por el momento para aplicaciones de producción) como la herramienta ideal.

    Me gustaría conocer vuestra opinión al respecto

    Muchas gracias

    Responder
  14. Vio

    Hola Jose:

    Te comento entre líneas:

    1. No poder abrir más de un datacontext, no poder “desattachar” (estoy usando VS200 y tener que utilizar una instancia pública.

    Las clases datacontext tienen cuatro constructores, uno de ellos tiene un parámetro del tipo string. En ese string le puedes pasar la cadena de conexion que quieras e instanciarte dos contextos diferentes, uno en la base de datos A y el otro en B, y tienes dos contextos diferentes de bases de datos diferentes. Con respecto a lo de “desattachar”, LINQ to SQL se basa en el modelo desconectado, por lo que todos sus elementos están “desattachados”, además del concepto de carga retrasada. Lo que hace LINQ to SQL es hacer un seguimiento de los cambios que se van realizando a los objetos, y cuando se llama a submitchanges realiza todas las modificaciones en una transacción, es decir, si alguna operación falla, la base de datos se queda como está.

    2. Problema con el refresco en los binding de datos en controles.

    Es la primera noticia que tengo, pero viendo el punto 1, creo que lo que te ocurre es que refrescas el binding ántes de hacer un submitchanges.

    Espero que te sirva.

    Un saludo.

    Responder
  15. dalia

    hola ojala q me ayuden con esta conexion yo estoy usando WPF y estoy tratando hacer linq to sql pero no me reconoce.
    Dim guardar As New Guardar_ContactosDataContext
    a la variable guardar me sale el error :

    error de resolucion de sobrecarga porque ninguna de las funciones ‘New’ a las que se tiene acceso acepta este numero de argumentos.

    ???
    gracias

    Responder
  16. matias

    hola,muy bueno tu foro, me esta sirviendo mucho para todo lo relacionado a .net, solo tengo un problema,: instale visual web developer express 2008 con sp1 y en la instalacion tambien em instalo sql server 2008 express, la cosa es q cuando quiero agregar una base de datos en un proyecto web en asp.net me sale el siguiente error:

    No se pudo generar una instancia de usuariode SQL Server debido a un error al iniciar el proceso para la instancia de usuario. se cerrara la conexion.

    la verdad es q por mas q pregunte en foros nadie me responde a esta pregunta y decidi recurrir a este medio, q por lo q veo estas bien metido en el tema, gracias.

    como otra dato en el SQl Server configuration manager hay 3 servicios
    SQL server browser, SQL server (express) y Agente SQl server.
    de estos 3 solo em dejar en ejecucion al sql server espress, lso demas ni em deja activarlos o darle al play.

    me parece raro ya q en la instalacion q se llevo a cabo junto con la de visual web developer 2008 no salto ningun error, bue de antemano gracias por tu ayuda.

    Responder
  17. Strun

    Tengo el mismo problema que Matías.

    He probado a reinstalar, instalar SQL Server 2005, pero me sigue saliendo el mismo error con el Visual Studio 2008. Llevo mucho tiempo perdido con esto y seguro que es alguna tontería.

    Si alguien sabe algo me salva el culo. :D

    Muchas gracias.

    Responder
  18. Israel

    Hola muchas gracias por el tutorial apenas estoy por aprender algo de LINQ ya tengo algo de rato con versiones anteriores, gracias por tomarte el tiempo de compartir esto!!

    Responder
  19. Omar

    Pregunta para VIO:
    ¿LINQ to SQL funciona también para MySql Server ó solo para MS Sql Server?, es que intenté y por más que quise no funcionó (Con MySql).

    Lo que me parece genial es la integración de consultas al lenguaje de programación, buen aporte, espero tu respuesta =)

    Responder
  20. Pingback: LINQ | Un Mundo Interesante ....

  21. zelski

    Tengo una duda enorme, cuando abres o instancias el datacontext se abre la conexion a la base de datos, se hacen las operaciones necesarias, pero, he aqui mi duda, como se que la conexion se ha cerrado, o en su caso como debo cerrarla?, con connection.Close() ???, por que apenas me ha salido un error de pool connection, en donde al parecer habia demasiadas conexiones abiertas.

    Gracias de antemano.

    Responder
  22. Pingback: ASP.NET MVC Framework (Primera parte) « Thinking in .NET

  23. Leonardo Novoa

    Hola, tengo un gran problema o pues para mí lo es. Llevo dias quemandome las pestañas frente al pc y no he podido arreglar un inconveniente, claro como siempre cualquier cosa es fácil para aquel que domina el tema. Les solicito porfavor, alguien me puede colaborar con este inconveniente. Estoy trabajando con linq, tenia dos procesos, y funcionaban correctamente, en una aplicación windows forms, finalmente me solicitaron que colocara los dos procesos en hilos independientes lo realice, pero obtuve problemas de concurrencia, ya que usaba el mismo datacontext y los procesos usaban esta conexión, por tanto cree un nuevo datacontext cada vez que necesitaba hacer alguna acción en la base de datos con el segundo, pero me arroja un error que dice que no se puede adjuntar una entidad que ha sido creada con otro datacontext, no se entonces que pueda hacer. Les sería muy agradecido si me colaboraran con esto. Mil gracias. Hasta luego.

    Responder
  24. yo

    hola quisiera hacer con LINQ un giro de una tabla, es decir, la función PIVOT de SQL pero para LINQ. Las columnas que querría pasar a filas son dinámicas por lo que no me sirve nada en lo que hay que poner columnas por defecto.

    Gracias!

    Responder
    1. Alex

      Visual foxpro ya tenia muchas de las cosas que recien estan inventando para .NET y para JAVA solo que no corria para la Web

      muy bonito LINQ pero prefiero trabajar todo a mano para aplicaciones de alto rendimiento, pero si voy hacer un misio CRUD pues mejor usar LINQ

      Responder
  25. martin

    Error: when say: “La versión “Orcas” del .NET Framework biene con librerías que habilitan LINQ sobre objetos, XML y bases de datos.”

    The word “biene” be write with “v”

    thank’s

    Responder
  26. Miguel

    Hola!!
    estuve probando el código planteado en tus ejemplos, pero cuando intete eliminar un registro de la Base de datos, busque el método el removeAll y no lo encontré, osea no aparece en el Intellicense y me sale un error alli.

    Es en esta parte: db.
    Products.RemoveAll(product);
    porfavor me puedes ayudar
    muchas gracias…

    Responder
  27. Alex

    Saludos, excelente tutorial, desarrollo en ASP.NET tradicional pero me quiero actualizar. Estaba siguiendo tu tutorial pero el PDF se corta en algunas secciones claves. ¿Podrías enviarme los fuentes por favor?, te estaría muy agradecido, mi correo es: deviloper87@gmail.com

    Gracias de antemano.

    Responder
  28. Luis

    mis hermanos, están llenos de sabiduría. Voy a seguir su tutorial paso a paso, es raro encontrar tutoriales tan bien explicados, ahorita estoy en el proceso de aprender .NET usando entidades, linq y toda esta nueva tecnología, espero nos podamos apoyar mutuamente, un abrazo desde México!!

    Responder
  29. Pingback: links de programacion con c# y linq | Academia Bhargo

Deja un comentario