[Entity Framework] Separando el Acceso a Datos de la Interfaz de Usuario, Parte II – Self-Tracking Entities – WCF

Hola, continuando con esta serie de post de este excelente ORM, llegamos al punto en el que queremos separar de una vez por todas la entidades de nuestro contexto y poder ademas consumir este, sin que la presentación conozca el acceso a datos.

Para esto, haremos uso de un nuevo elemento implementado en Visual Studio 2010 y que es especial para el trabajo con Entity Framework, se trata de Self  Traking Entities,  emplearemos un WCF quien sera el encargado del negocio, este conocerá nuestras entidades y nuestro contexto, y presentara a la interfaz de usuario el resultado de las operaciones, pero bueno basta de charla y manos al teclado.

Lo primero que haremos sera iniciar Visual Studio 2010, crearemos una solución en blanco, sobre esta agregaremos dos proyectos uno de librería de Clases [AccesoDatos] y uno de interfaz de usuario, en mi caso Consola esta bien. Sobre la class Library agregamos un elemento del tipo Entity DataModel y hacemos lo que ya sabemos hacer, conectarnos a un modelo físico.

Agregaremos sobre la solución un nuevo proyecto del tipo Class Library y lo llamaremos Entidades [Eliminamos la clase que VS nos genera por defecto].

Ahora sobre nuestro proyecto de AccesoDatos agregamos un nuevo elemento, localizado en la sección Code y que se llama ADO.NET Selft Tracking Entity Generator, este sera el encargado de crearnos, a partir de un .edmx dos plantillas t4 (.tt) con lo que necesitamos [explicación mas adelante :P].

Con esto se nos habrá generado dos ficheros de extinción .tt, el archivo <Modelo>.tt sera el que contenga nuestras entidades de dominio y ademas una clase auxiliar que contendrá en su interior la lógica del seguimiento de cambios que utilizan las entidades de Selft Tracking Entities y los métodos de extensión que permiten establecer el estado de estas. El archivo <Modelo>.Context.tt genera una clase ObjectContext con tipo y una clase de extensión que contiene los métodos ApplyChanges para las clases ObjectContext y ObjectSet.

Ahora bien, para que nuestros ficheros tt’s conozcan el Modelo conceptual debemos definirlo en las lineas:

string inputFile = @”ModeloDemo.edmx”;

Adicional podemos eliminar el Custom Tool del modelo conceptual, pues ya no lo usaremos mas 😀

Lo siguiente sera separar las entidades de esta librería, para esto, cortamos la t4 que contiene las entidades y las pegamos sobre el proyecto Entidades. Una vez hecho esto, se debe cambiar  la definición de el valor inputfile de este, pues ya no se encuentra en la misma carpeta, e mi caso seria así:

string inputFile = @"..\AccesoDatos\ModeloDemo.edmx";

Lo que sigue es sobre el proyecto Entidades agregar una referencia al ensamblado System.Runtime.Serialization, pues estas entidades que nos genera son serializables. Como paso final Agregaremos una referencia de nuestro proyecto de Entidades a el proyecto de AccesoDatos, pues el contexto debe conocer a sus entidades de domino y en la plantilla t4 debemos indicar que se debe hacer uso de esta, para eso definimos a manera de string un segundo parametro en la linea WriteHeader(), así:

WriteHeader(fileManager, "NombreEnsamblado");

En este momento nuestra solución debería lucir así:

[Nota: debe verse ademas el App.Config en el proyecto de AccesoDatos no se ve aquí porque es una demo ya terminada :D]

Como paso siguiente agregaremos un nuevo proyecto a solución, este sera un WCF Service Application, así:

Sobre este proyecto agregaremos una referencia a los ensamblados de Entidades y AccesoDatos, ademas sera necesario agregar una referencia a el ensamblado System.Entity.Data y copiar la Connection String de nuestro App.Config de el proyecto AccesoDatos a el Web.Config de nuestro WCF. el App.Config puede ser eliminado sin problemas de nuestro proyecto de AccesoDatos.

Del lado del código, en la definición del servicio definiremos los métodos necesarios para trabajar con nuestras entidades, así:

using System.Collections.Generic;
using System.ServiceModel;
using Entidades;
namespace WCF
{    
    [ServiceContract]
    public interface IEfDemo
    {
        [OperationContract]
        List<Pais> ObtenerPaises();

        [OperationContract]
        int Modificar(Pais pais);

        [OperationContract]
        Pais ObtenerPaisPorId(int id);

        [OperationContract]
        int InsertarPais(Pais pais);

        [OperationContract]
        int ModificarPaisPorId(int id);
    }   
}

Y del lado de la implementación:
using System.Collections.Generic;
using System.Linq;
using Entidades;
using AccesoDatos;
namespace WCF
{
    public class Service1 : IEfDemo
    {
        public List ObtenerPaises()
        {
            using (EFDemoEntities context = new EFDemoEntities())
            {
                return (from p in context.Pais
                        select p).ToList();
            }
        }
        public int Modificar(Pais pais)
        {
            using (EFDemoEntities context = new EFDemoEntities())
            {
                context.Pais.ApplyChanges(pais);
                return context.SaveChanges();
            }
        }
        public Pais ObtenerPaisPorId(int id)
        {
            using (EFDemoEntities context = new EFDemoEntities())
            {
                return (from p in context.Pais
                        where p.Id == id
                        select p).First();
            }
        }
        public int InsertarPais(Pais pais)
        {
            using (EFDemoEntities context = new EFDemoEntities())
            {
                context.Pais.AddObject(pais);
                return context.SaveChanges();
            }
        }
    }
}

Cosas a observar, el método context.Entitie.ApplyChanges():

Como paso siguiente, seleccionamos como proyecto de inicio el proyecto de WCF y ejecutamos, VS nos generara un servidor de desarrollo con la url y el puerto para nuestro servicio, luego se agrega la referencia al servicio en la interfaz de usuario [click inverso, Add Service Reference] en este caso seleccionaremos la opción Discover, Go y

Generamos una instancia del ServiceClient, apuntamos  a uno de los métodos y listos 😀 tenemos una aplicación separada en capas con servicios de WCF y Self Tracking Entities.

[Nota: Para que el método que retorna lista genérica funcione, en presentación, es necesario configurar la referencia del servicio para que sus Collection Type sean Colecciones genéricas], así:

Con esto llegamos al final del post.

Espero les sea de utilidad.

Descarga el ejemplo

Hasta el próximo post

Anuncios
[Entity Framework] Separando el Acceso a Datos de la Interfaz de Usuario, Parte II – Self-Tracking Entities – WCF

3 comentarios en “[Entity Framework] Separando el Acceso a Datos de la Interfaz de Usuario, Parte II – Self-Tracking Entities – WCF

  1. Buenas! Tengo la siguiente duda…suponiendo que separamos las plantillas en un proyecto aparte, como en este caso, que sucede si actualizamos el modelo EDM? Las clases POCO se reemplazan por las nuevas, perdiendo cualquier modificacion que hayamos hecho sobre ellas, o al estar en un proyecto separado estas se mantienen igual y debemos modificarlas manualmente?? saludos!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s