sábado, 1 de septiembre de 2012

WCF 4 Parte 1: LINQ y Entity Framework

Estoy en el proceso de leer un libro sobre WCF y, como mencioné en el post anterior, me parece una muy buena práctica el dejar notas respecto a este tipo de lecturas, por lo tanto voy a ir dejando algunas entradas en el blog respecto al libro “WindowsCommunication Foundation 4”. Como en el post anterior lo recomendable es hacerse con el libro y leerlo, pues más bien estas notas vienen siendo personales, con muchos vacíos, detalles que se asumen, etc.


Ahora bien, voy a tratar de realizar una serie de post con ejemplos de WCF. El primero tratará sobre un inventario. Voy a tener dos tablas: una de productos y otra de inventario. La primera tendrá columnas como el id del  producto, descripción, precio y la segunda también el id producto, número de bodega y cantidad en stock. En realidad muy sencillo.


Para este ejemplo se usan varias tecnologías como Entity Framework, Linq y el propio WCF. Este primer post tratará de juntar las piezas y crear un servicio WCF que me devuelva todos los id productos de la base de datos, para luego, en entradas posteriores, hacer otros métodos que me devuelvan el detalle de un producto, consultar el stock de un producto en todas las bodegas y actualizarlo.

Buenos, ¡manos a la obra!.  Ya contamos con las tablas creadas en nuestro SQLServer. Ahora vamos a Visual Studio. Primero vamos a usar el Entity Framework para crear nuestras entidades de programación a partir de las tablas en nuestra base de datos. Para lograr esto primero creamos un proyecto de tipo Class Library, le ponemos como deseemos (en mi caso ModeloProductos); una vez creado, eliminamos la clase que crea por defecto el wizard.

A continuación hacemos clic derecho sobre el proyecto y elegimos Add New Item, en esta nueva ventana elegimos ADO.NET Entity Data Model le nombramos como deseemos (ModeloProductos) y clic en Add. Nos aparecerá un wizard en el que elegiremos Generate From Database, a continuación nos pedirá establecer una conexión, esta deberá estar apuntando a la DB donde tenemos nuestras tablas. Una vez establecida la conexión hacemos clic en Next y nos parecerá una ventana en la que eligiremos que objetos de la base de datos incluir en nuestro de modelo


 Elegimos la tablas deseadas y, si queremos, cambiamos el namespace del modelo para seguidamente hacer clic en Finish. Y “voilà”, están listas nuestras entidades.



Ahora comencemos con el  servicio WCF. Hacemos clic derecho sobre la solución y elegimos Add -> New Web Site… En la pantalla que nos aparece, de los Online Templates, elegimos WCF Service


Este wizard crea dos clases en el folder App_Code: IService.cs y Service.cs.  El primero de estos es la interfaz que define las operaciones que contendrá el servicio y el segundo es la implementación de esta definición. Es algo así como un contrato que engloba todo lo que el servicio debe hacer y la implementación propiamente de los pasos necesarios para llevar acabo lo especificado en el contrato.

Renombremos las clases según deseemos (IProductoServicio.cs y ProductoServicio.cs en mi caso). Comencemos con la interfaz, el contrato, en el archivo IProductoServicio.cs eliminamos todo el código dejando únicamente las directivas using, añadimos el siguiente código:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace TestWCF
{
    [ServiceContract]
    public interface IProductoServicio
    {
        // devuelve el id de todos los productos
        [OperationContract]
        List<string> ListaProductos();
    }
}

La interfaz se decora con la etiqueta ServiceContract que indica que es un contrato que debe implementarse, cada operación de este contrato debe decorarse con la etiqueta OperationContract para indicar que son operaciones del contrato a implementar. En este caso nuestra operación no recibe parámetros y devuelve una lista de strings correspondientes a los id de los productos. Se pueden usar listas siempre que los tipos que devuelvan sean serializables, de hecho todo lo que reciba el servicio así como lo que devuelva debe ser serializable. Notar además las directivas System.ServiceModel estas son las que contienen las bases para la creación del servicio WCF.

Ahora la implementación, en el archivo ProductoServicio.cs dejamos únicamente las sentencias using. Luego necesitamos añadir las referencias para utilizar las entidades del Entity Framework, para esto hacemos clic derecho sobre el proyecto y luego elegimos Add Reference, elegimos nuestro proyecto de Entidades (en mi caso ModeloProductos); luego volvemos añadir otra referencia pero esta vez buscamos en la pestaña .Net y añadimos la referencia System.Data.Entity. Ahora con esto finalmente añadimos el código de la operación quedando de la siguiente manera:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using ModeloProductos;

namespace TestWCF
{
    public class ProductoServicio : IProductoServicio
    {
        public List<string> ListaProductos()
        {
            // Se crea la lista para los id de Productos
            List<string> listProductos = new List<string>();
            try
            {
                // Conectando a la base de datos usando Entity Framework
                using (TestDBEntities db= new TestDBEntities ())
                {
                    // LINQ para obtener la lista de id de los productos
                    var products = from producto in db.Productos 
                                   select producto.ProductoID;
                    listProductos = products.ToList();
                }
            }
            catch
            {
                // De momento no se implementa el manejo de excepciones
            }
            // devuelve la lista de productos
            return listProductos;
        }
    }
}

Primero crea la lista de string para meter los id productos, luego usando Entity FrameWork nos conectamos a la base de datos; usamos Linq para realizar una consulta simple de los id de productos, el resultado lo transformamos en una lista y finalmente devolvemos esa lista.

Ya con esto esta casi listo el servicio, faltan algunos detalles de configuración. Primero en la raíz de proyecto ubicamos el archivo Service.svc, este archivo apunta a la implementación del servicio. Lo modificamos para que apunte al archivo y clase correctos:

<%@ ServiceHost Language="C#" Debug="true" Service="TestWCF.ProductoServicio" CodeBehind="~/App_Code/ProductoServicio.cs" %>

Notar que en el valor de Service se pone el nombre de la clase con todo y namespace.

Finalmente necesitamos el string de conexión a la base de datos en el archivo de configuración del sitio. Para esto nos fijamos en el archivo App.config del proyecto Enttiy Framework y copiamos todo lo que este entre las llaves <connectionStrings> estas inclusive y luego copiamos esto en web.config del sitio del servicio, luego de la apertura de la llave <configuracion> pero antes de la llave <system.web> de la siguiente manera:

<?xml version="1.0"?>
<configuration>
  <connectionStrings>
    <add name="TestDBEntities" connectionString="metadata=res://*/ModeloProductos.csdl|res://*/ModeloProductos.ssdl|res://*/ModeloProductos.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=FOYPC\FOYSERVER;initial catalog=TestDB;integrated security=True;multipleactiveresultsets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>
  <system.web>

El resultado final es similar a un web service, pero en WCF. Para probar que todo esta bien ejecutamos el servicio, como cualquier sitio web y nos debe aparecer algo parecido a esto:

                                
Notar que esta corriendo en el servidor de desarrollo de Visual Studio, cuando lo ideal sería que se ejecutase en el IIS, quedará para una próxima entrada. Nos falta construir una aplicación cliente para consumir este servicio, pero como este post ya se ha extendido mucho lo dejo para la siguiente entrada.

0 comentarios: