3.05.2011

El Entity Framework en una Arquitectura n-Layer – Parte 7 –{ Polimorfismo por Herencia }

Siguiendo con el post anterior, vamos a proceder a guardar una entidad heredada utilizando el polimorfismo por herencia en el Entity Framework. Dado que en el post anterior modificamos el esquema de entidades generado por el Entity Framework para agregar herencia, podemos aprovecharnos de esta característica para hacer métodos polimórficos en la lógica de Negocios.

Polimorfismo en .NET

En realidad existen 3 formas de polimorfismo presentes en .NET: Polimorfismo por herencia, polimorfismo por Abstracción y polimorfismo por interface – mi preferida. En este caso vamos a utilizar el polimorfismo por herencia, dado que como podemos ver en la siguiente figura una vez hecho el cambio de la herencia de las entidades del post anterior, ambas entidades creadas – contratista y empleado regular– heredan de Empleado.

image

El primer paso es crear la clase de negocios para la entidad Empresa, ya que todos los empleados tienen una empresa asociada y esto se tiene que utilizar en el UI que vamos a crear para agregar empleados contratistas.

image

Ahora en la clase EmpresaBL procedemos a agregar el código necesario para acceder a la colección de empresas presentes en la base de datos.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HerenciaEF.DAL;

namespace HerenciaEF.BL
{
public class EmpresaBL
{
public List<Empresa> ObtenerEmpresas( )
{
var _empresas = from e in EFCommon.ObtenerContexto().Empresa select e;
return _empresas.ToList();
}
}
}

Nótese que esta vez ya no estamos creando una instancia del modelo del entity framework si no que estamos utilizando un método estático de la clase EFCommon llamado ObtenerContexto. Entonces primero debemos crear una clase que se llame EFCommon


image


Seguidamente procedemos a codificar el manejo del contexto dentro de nuestra nueva clase.

using HerenciaEF.DAL;

namespace HerenciaEF.BL
{
public static class EFCommon
{
static Ejemplos_BlogEntities1 _contexto = null;
public static Ejemplos_BlogEntities1 ObtenerContexto( )
{
if (_contexto == null)
_contexto = new Ejemplos_BlogEntities1();
return _contexto;
}

}
}

Algo importante de destacar, que aquí se utiliza un singleton porque estamos utilizando una aplicación desktop, lo que no es recomendable de hacer en una aplicación Web por ejemplo – tema que trataremos en post posteriores.


Seguidamente procedemos a agregar el método para agregar los nuevos empleados. Igualmente los métodos para obtener los diferentes tipos de empleados se cambiaron para que utilicen la clase EFCommon.

public List<EmpleadoDePlanta> ObtenerEmpleados( )
{
var empleadosDePlanta = EFCommon.ObtenerContexto().Empleado.OfType<EmpleadoDePlanta>();
return empleadosDePlanta.ToList();
}

public List<EmpleadoContratista> ObtenerEmpleadosContratistas( )
{
var empleadosContratistas = EFCommon.ObtenerContexto().Empleado.OfType<EmpleadoContratista>();
return empleadosContratistas.ToList<EmpleadoContratista>();
}

public int GuardarEmpleado( Empleado pEmpleado )
{
EFCommon.ObtenerContexto().AddObject( "Empleado", pEmpleado );
return EFCommon.ObtenerContexto().SaveChanges();
}

Y en el método GuardarEmpleado esta el polimorfismo. Nótese que no estamos esperando una instancia de empleado contratista o de empleado de planta, si no que esperamos una instancia de empleado. Esto se puede hacer porque ambas entidades heredan de Empleado y pueden convertirse a la clase base y viceversa sin perder su estado – Que poderoso es el polimorfismo :P -


El siguiente paso es crear una pantalla para guardar un empleado contratista


image


Luego agregamos el código para llenar el combo de las empresas para que el usuario final pueda seleccionar la empresa del contratista a agregar.

public AgregarContratista( )
{
InitializeComponent();
EmpresaBL _empresas = new EmpresaBL();
cmbEmpresa.DisplayMemberPath = "Nombre";
cmbEmpresa.ItemsSource = _empresas.ObtenerEmpresas();
}

Seguidamente agregamos el código para agregar el empleado que se desea ingresar a la base de datos.

private void btnGuardar_Click( object sender, RoutedEventArgs e )
{
EmpleadoContratista _contratista = new EmpleadoContratista();
_contratista.Nombre = txtNombre.Text;
_contratista.Telefono = txtTelefono.Text;
_contratista.Email = txtEmail.Text;
_contratista.CostoXHora = Convert.ToDecimal( txtCostoXHora.Text );
_contratista.Empresa = cmbEmpresa.SelectedItem as Empresa;

EmpleadoBL _empleadoBL = new EmpleadoBL();
_empleadoBL.GuardarEmpleado( _contratista );
}

Importante destacar -  y no me voy a cansar de hacerlo – que pese a que el tipo del parámetro del método GuardarEmpleado es empleado y el tipo que se le envía es empleado contratista, el método funciona sin problema; ya que como comenté antes se esta utilizando polimorfismo, lo cual es algo que siempre deberíamos considerar a la hora de crear aplicaciones.


Por último procedemos a ejecutar la pantalla para agregar nuevos contratistas.


image


Luego de ingresar el nuevo contratista, así aparece en nuestro Grid el cuál fue creado en el post anterior.


image


Un punto a destacar, es que si hacemos el query a la tabla de la base de datos, nos damos cuenta que el campo tipo empleado se lleno de forma automática por medio del EntityFramework, el cual utilizó la regla de mapeo creada en el capítulo 6 para hacer la inserción. En la siguiente figura se ve como al empleado Ernesto se le agrega como tipo “Contratista”.


image


Como podemos ver en este ejemplo, la herencia y sobre todo el polimorfismo son conceptos que debemos utilizar a la hora de crear nuestras aplicaciones, ya que esto le dará posibilidad de crecer sin necesidad de restructurar; ya que por ejemplo ahora al método AgregarEmpleado se le puede pasar cualquier entidad que herede de empleado sin necesidad de reescribir el código y recompilar.


5 comentarios:

Diego Rojas dijo...

Gracias Chris por el comentario

Anónimo dijo...

Porque no es recomendable utilizar singleton en una aplicación Web?

Diego Rojas dijo...

Gracias Anónimo por leer el blog.
Por que podría producir comportamientos inesperados a la hora de interactuar con el Entity Framework. En un post próximo voy a tratar el tema con amplitud

Arturo dijo...

Hola Luis.

Excelente esta serie de artículos sobre EF.

Volviendo a lo básico, ¿como es el polimorfismo por abstracción? y ¿porque tu polimorfismo favorito es usando interfaces? ¿que ventajas aporta?

Saludos

gyo dijo...

Ho esta excelente esta serie de post's cuando sea grande quiero saber lo que tu sabes :D saludos desde mexico pue