viernes, 29 de abril de 2011

LinQ to SQL en un ambiente Web


El objetivo de esta entrada es inaugurar este espacio donde humildemente tratare de mostrar las experiencias y desafíos tecnológicos con los que me enfrento cotidianamente con el deseo de documentar el esfuerzo y que pueda servir de ayuda para quienes lo necesiten.

Vamos a comenzar con un tema bastante útil y simple como es consumir linq desde un ambiente web para el acceso a datos.

¿Qué es LINQ?
Es un lenguaje integrado de consultas que nos permite trabajar con diversas fuentes de datos tomando ventaja del CLR en tiempo de compilación.

Arquitectura


En esta entrada nos vamos a centrar en LINQ a SQL, lo que vamos a ver en un ejemplo práctico, el cual consiste en acceder a una base de datos SQL Server a través de una capa intermedia de lógica de negocio.
Básicamente lo que haremos es un CRUD de un objeto Cliente utilizando LINQ a SQL

Lo primero que vamos a hacer es crear un nuevo proyecto de tipo aplicación web ASP.NET  en VS2010

Luego en la misma solución agregamos un proyecto de tipo biblioteca de clases donde alojaremos el mapeo de las clases con las entidades de la base de datos y la lógica.

Una vez agregado el proyecto, al mismo se le añadirá un nuevo elemento de tipo Clases de LINQ to SQL

Cuando esto se realice se mostrara un panel que me permitirá arrastrar entidades de la base de datos para que se generen, automáticamente, las clases correspondientes y también el mapeo objetos-entidades.
Yo ya tengo preparada una base de datos creada en SQL Server 2008, por lo que voy a arrastrar desde el explorador de servidores hacia mi panel.
Nota: recuerden establecer una clave primaria en las tablas.

Podemos observar que en el panel se muestra nuestra clase Cliente, con sus correspondientes atributos. Es de importancia aclarar que en el mapeo cada propiedad de las entidades tienen sus correspondencias con las propiedades de la clase.
Esto sería:
Entidad – Objeto
Columna – Atributo
Procedimiento almacenado – Método
Relación – Relación
…
El código de todas estas relaciones se genera automáticamente en el archivo .designer.cs.
En este archivo además del mapeo se declaran las clases y sus atributos. Si prestamos mayor atención en la declaración de la clase podemos notar que es de tipo partial, esto es una propiedad del lenguaje que me permite separar una clase en diferentes archivos de código. Así de esta forma puedo separar mi lógica en otro archivo y esta no se verá afectada si deseo realizar cambios en mi estructura de la base de datos.
Haciendo clic derecho sobre la clase en el panel podremos ver la opción “ver código” lo que me va a generar otro archivo .cs, con otra declaración de la clase parcial, donde voy a escribir mi lógica personalizada.
Para este caso voy a crear cuatro métodos con la lógica para mi CRUD.



using System;
using System.Linq;
using System.Collections.Generic;

namespace Logica
{
    partial class Cliente
    {
        public static IEnumerable<Cliente> clientes()
        {
            LogicaDataContext db = new LogicaDataContext();
            return from cliente in db.Cliente
                   select cliente;
        }

        public static void crear(Cliente cliente)
        {
            LogicaDataContext db = new LogicaDataContext();
            db.Cliente.InsertOnSubmit(cliente);
            db.SubmitChanges();
        }

        public static void modificar(Cliente cliente)
        {
            LogicaDataContext db = new LogicaDataContext();
            Cliente updateClietne =
                (from objCliente in db.Cliente
                 where objCliente.id == cliente.id
                 select objCliente).Single();
            updateClietne.Nombre = cliente.Nombre;
            updateClietne.Apellido = cliente.Apellido;
            db.SubmitChanges();
        }

        public static void eliminar(Cliente cliente)
        {
            LogicaDataContext db = new LogicaDataContext();
            Cliente deleteClietne =
                (from objCliente in db.Cliente
                 where objCliente.id == cliente.id
                 select objCliente).Single();
            db.Cliente.DeleteOnSubmit(deleteClietne);
            db.SubmitChanges();
        }
    }
}

Bien, paso a defenderme respecto a algunas malas prácticas de la programación orientada a objetos.
En primer lugar notaran que los métodos son estáticos y además toman como parámetro un objeto de la misma clase, entonces yo me voy a adelantar en el post y les voy a aclarar que esto se debe a que para consumir este código voy a utilizar un control de enlace para la presentación que es ObjectDataSource y me veo forzado a escribir los métodos de esta manera.
Respecto a la instancia de la clase LogicaDataContext se estarán preguntado de que se trata, es nada más y nada menos que la clase generada en el archivo .disegner.cs que contiene el código del mapeo y definiciones de clases.

Ya tengo mi lógica personalizada ahora la voy a consumir desde la presentación. Para esto voy a ir a mi proyecto web, voy a agregar una referencia a mi biblioteca de clases y voy a compilar para poder ver mi clase.
En la página que se generó al crear el proyecto o una que ustedes deseen agregar, vamos a agregar dos controles de presentación, un GridView y un DetailsView, además del ObjectDataSource para enlazar con la capa de lógica.

A través de la etiqueta inteligente de mi ObjectDataSource voy a configurar el enlace.


Es muy sencilla esta tarea gracias al asistente que nos proporciona VS, de esta forma seleccionamos cada metodo para su propositoy le damos finalizar

Ahora vamos a configurar nuestros controles de presentación

GridView:
Mediante la etiqueta inteligente seleccionamos su origen de datos el cual es nuestro ObjectDataSource
Habilitamos las casillas para edición y eliminación también en la etiqueta inteligente
En las propiedades vamos a establecer el atributo id como DataKeyNames

DetailsView:
Mediante la etiqueta inteligente seleccionamos su origen de datos el cual es nuestro ObjectDataSource
Habilitamos las casillas para inserción también en la etiqueta inteligente
En las propiedades vamos a establecer el atributo id como DataKeyNames
También establecemos la propiedad DefaultMode en Insert con el propósito de utilizar este control para las altas

Debería quedar algo así:

Por ultimo ejecutamos y vemos nuestra aplicación funcionar.

Para muchos este post resultara algo básico pero me pareció adecuado para aquellos quienes comienzan a incursionar en esta tecnología. Espero que le saquen provecho y acá les dejo un link interesante de donde podrán obtener ejemplos de consultas LINQ http://msdn.microsoft.com/en-us/vcsharp/aa336746.

Saludos y hasta el próximo post.







No hay comentarios:

Publicar un comentario