jueves, 17 de mayo de 2012

Generación de clases POCO


Estoy haciendo un curso de desarrollo de Asp.net  y así me desintoxico de tanto winforms impartido por CampusMVP (altamente recomendable!!!) y me ha surgido una duda.

Estaba viendo los DataAnnotations para un ejemplo en MVC y me planteaba el poder generar las clases “buddy” automáticamente del Entity Framework en vez de crearlas de nuevo para aplicarles las annotations.  Pensaba en esas tablas de más de 30 campos que suelen haber en escenarios reales.

No me acordaba que el Entity Framework es un generador automático de código.

Con Entity Framework y la plantilla adecuada se pueden generar clases POCO, (Plain Old CLR Objects) o, traducido, Objetos simples y planos.

Entity Framework es un generador de código


El Entity Framework, cuando se compila, genera un “code-behind” del archivo EMDX (con extensión Desiger.cs) que contiene un código autogenerado a partir del modelo de entidades, que son en realidad los objetos que manejamos cuando trabajamos con él.

Si buceamos un poco dentro de ese archivo, encontraremos las regiones “Contextos” y “Entidades”.

Dentro de cada entidad,  “Métodos de generador”, “Propiedades primitivas” y "Propiedades de navegación".

Dentro de "Propiedades primitivas" tenemos las propiedades de la clase, aunque algo enmarañadas con el código que genera el Entity Framework, y que tanto papel nos hace (guardado, recuperación, intellisense, tipado, etc...)


Cambiando el generador de código por defecto.


Como hemos visto, el Entity Framework genera código. Podemos cambiar el generador de código por defecto por uno que funcione como queremos, o incluso, crear nosotros mismos las plantillas de generación de código. (Plantillas T4)



De hecho, el Entity Framework usa plantillas T4 para generar el modelo de entidades.


En la ventana de propiedades del Entity Framework, le estamos indicando que genere el código usando la plantilla T4 "SSDLToSQL10.tt"

Podemos cambiar el generador de código pulsando botón derecho en algún hueco del explorador de entidades del EF, y eligiendo "Agregar elemento de generación de código".



Nos aparecerán los generadores de código que tenemos instalados (El generador por defecto de Entity Framework y el generador de STE(Self-Tracking entities)).



Si pulsamos sobre Plantillas en línea, se muestran las plantillas disponibles a descargar.

Sobre el menú Base de datos, elegiremos EF 4.0 DBContext Generator for C# (me imagino que también habrá para VB.NET)


Al instalar esta plantilla se guardan en nuestro proyecto 2 plantillas t4 vinculadas al modelo de Entity Framework. Una contiene el contexto y otra las entidades.



TACHAAAAN. Ya tenemos generadas las entidades POCO




Detalle del contexto.

        public DbSet<Category> Categories { get; set; }
        public DbSet<CustomerDemographic> CustomerDemographics { get; set; }
        public DbSet<Customer> Customers { get; set; }
        public DbSet<Employee> Employees { get; set; }
        public DbSet<Order_Detail> Order_Details { get; set; }
        public DbSet<Order> Orders { get; set; }
        public DbSet<Product> Products { get; set; }
        public DbSet<Region> Regions { get; set; }
        public DbSet<Shipper> Shippers { get; set; }
        public DbSet<Supplier> Suppliers { get; set; }
        public DbSet<Territory> Territories { get; set; }

Detalle de una entidad

    public partial class Employee
    {
        public Employee()
        {
            this.Employees1 = new HashSet<Employee>();
            this.Orders = new HashSet<Order>();
            this.Territories = new HashSet<Territory>();
        }
   
        public int EmployeeID { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public string Title { get; set; }
        public string TitleOfCourtesy { get; set; }
        public Nullable<System.DateTime> BirthDate { get; set; }
        public Nullable<System.DateTime> HireDate { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string Region { get; set; }
        public string PostalCode { get; set; }
        public string Country { get; set; }
        public string HomePhone { get; set; }
        public string Extension { get; set; }
        public byte[] Photo { get; set; }
        public string Notes { get; set; }
        public Nullable<int> ReportsTo { get; set; }
        public string PhotoPath { get; set; }
   
         public virtual ICollection<Employee> Employees1 { get; set; }
        public virtual Employee Employee1 { get; set; }
        public virtual ICollection<Order> Orders { get; set; }
        public virtual ICollection<Territory> Territories { get; set; }
    }



Para que nos compile esta plantilla sería necesario tener Framework 4.1 (usa System.Data.Entity.Infrastructure),  y encima tenemos deshabilitado el generador predeterminado de Entity Framework para que no se generen entidades duplicadas, pero para lo que queremos, que es obtener las clases POCO de nuestras entidades, no es necesario.

 Así que copiamos las clases generadas en una carpeta, y deshagamos el camino.


Volvamos al generador de código por defecto.

 

¿Qué ha pasado con el Entity Framework?

Las nuevas plantillas están usando las entidades del EF, pero éste está deshabilitado.


Fijémonos en las clases generadas por el Entity:

// La generación de código predeterminada está deshabilitada para el modelo 'C:\*******\MvcApplication1\MvcApplication1\Models\Model1.edmx'.

// Para habilitar la generación de código predeterminada, cambie el valor de la propiedad del diseñador 'Estrategia de generación de código'

// por otro valor. Esta propiedad está disponible en la ventana Propiedades cuando se abre

// el modelo en el diseñador.



Para deshacer el camino, borramos las dos plantillas T4 que ha creado la plantilla (los ficheros *.tt) y cambiemos la propiedad del Entity Framework "Estrategia de generación de código" a "Predeterminados"
 

Con esto hemos conseguido generar unas clases POCO que nos pueden servir para muchas cosas, como para las validaciones con MVC y DataAnnotations, clases para pasarlas entre capas, etc.

Saludos!!!

No hay comentarios: