EntityFramework con repositorios genéricos

computer-1185626_1280
EntityFramework es una herramienta que le permite a los programadores tener una capa más de abstracción entre su aplicación y su base de datos. Con EntityFramework podemos crear tablas ligadas a nuestras clases, y con ello viene la ventaja de poder ir versionando nuestra base de datos. Pero EntityFramework no es el único ORM en el mercado, existen otros entre Dapper, Massive y PetaPoco.

Entre todas las opciones existentes de ORM y de diferentes gestores de bases de datos, viene siendo aún más importante ir creando una capa entre la lógica de la aplicación y la base de datos. Para ello, los programadores suelen utilizar el patrón de repositorios genéricos, con unas cuantas funciones. Estas se mantienen igual, y lo que cambian son sus implementaciones.

Con .NET Core, la situación se vuelve más sencilla, ya que permite “inyectar” el repositorio encargado. La clase (o un controlador) desconoce quien la implementa, simplemente la usa. La forma de implementación no es de su incumbencia y al menos así podemos evitar la cohesión entre clases, que a la larga provocan problemas.

Como se puede observar en el código siguiente, existe una variable llamada “repository”, este se encarga de agregar la entidad/registro en la base de datos. La función Index (que es una acción de un controlador) no conoce ni quién, ni cómo la implementa, simplemente la usa. ¿El beneficio? en cualquier momento podemos cambiar de SqlServer a MySQL o MongoDb, sin necesidad de mover esa función.

Prerequisitos

Este artículo asume que se está usando Visual Studio 2015. Para poder continuar, se requiere de igual forma, modificar el archivo project.json (archivo del proyecto) para incluir los siguientes paquetes.

  • “Jaguar.DataAccess.EntityFramework” es un paquete que contiene el repositorio genérico, es una versión estable, pero que se entrega sin responsabilidad alguna de parte del autor, su código fuente estará pronto en Github.
  • “Microsoft.EntityFrameworkCore.SqlServer” es el paquete que permite conectarse especificamente a SQL Server. Este puede cambiarse de acuerdo a la página oficial.
  • “Microsoft.EntityframeworkCore.Tools” nos permite ir actualizando la base de datos conforme vamos haciendo los cambios.

Crear un modelo

En un ORM, cada modelo es una clase que esta enlazada a una tabla en la base de datos. De tal forma que el programador simplemente crea la clase y -en este caso- EntityFramework se encarga de realizar el resto.

Para el repositorio genérico, cada una de las clases deben implementar una interfaz. De tal manera que todas compartan al menos los requeridos para el repositorio. Esa interfaz en este caso es la de Jaguar.DataAccess.IEntity.

Cada clase debe tener al menos un campo clave que lo identifique. De manera predeterminada los campos llamados Id, o CustomerId son considerados automáticamente “campos claves”. IEntity, utiliza un campo tipo Guid.

Crear un contexto de EntityFramework

Para que EntityFramework pueda identificar que clases creará en la base de datos, estas se deben de poner en un “contexto”, para ello se requiere de crear una clase como la siguiente:

Solía suceder que EntityFramework utilizaba el nombre de la clase para compararlo en el webconfig en busca de una cadena de conexión, sin embargo en este caso (EntityFrameworkCore) las cosas ya no son así.

Es por eso que en la clase se crean como minímo 3 funciones, las primeras dos son constructores y la última es la que configura la cadena de conexión.

En el caso de los constructores, uno es utilizado por el repositorio para obtener la configuración recibida por el DI (inyección de dependencias) de .NET. El segudo, para los comandos de migración que se explica más adelante.

La última propiedad, es la interesante, básicamente ahí decimos que se creará una tabla de “Customer”.

Configurar DI

La inyección de dependencias es algo muy útil, y en este caso la usaremos en el archivo Startup.cs para poder crear la relación con el repositorio.

En este punto, existe una extensión que permite configurar ese contexto, para que sirva como el repositorio. A ese repositorio se le debe pasar la cadena de conexión, así que para ello, se debe configurar el archivo “appsettings.json”.

La base de datos que se usa en la cadena de conexión ha sido creada previamente, y asignado los permisos requeridos al usuario.

Creando las tablas (migración)

Con EntityFrameworkCore, los comandos cambiaron. Entre los paquetes que se instalaron en el proyecto se encuentra “Microsoft.EntityframeworkCore.Tools”, el cual es el encargado de crear los comandos necesarios para las migraciones.

Primero se debe generar las rutinas que se cargaran a la base de datos, corra los siguientes comandos para crear las tablas.

cd "srcmiapp"
dotnet ef migrations add inicial
dotnet ef database update

Al finalizar, las tablas fueron creadas en la base de datos. Considere correr esos comandos en el directorio principal de la aplicación donde esta el archivo “project.json”.

Haciendo uso del repositorio genérico

La inyección de dependencias (DI) es un concepto sencillo de comprender. El programador elabora un contrato, que tiene ciertas claúsulas. Todas esas cláusulas son obligatorias, de tal manera que al “contratar” a alguién, este debe de cumplir con dichas cláusulas. El contrato es una interfaz, que contiene las funciones que se ejecutará, pero no la implementación.

De tal manera, que en el paso anterior se especificó a .NET que el encargado del repositorio será la clase DataContext. Esta clase es la que ya se hizo anteriormente, es posible que al observar se de cuenta que la clase extienda la clase “Jaguar.DataAccess.EntityFramework.RepositoryContext” al mismo tiempo implementa la interfaz IRepository.

Con ello, .NET es capaz de inyectar en el constructor de la clase (HomeController), una instancia de DataContext con los métodos que tiene la interfaz IRepository.

Como se puede observar en el código anterior, existe un controlador que recibe el repositorio. Este lo asigna a una variable para que pueda ser usada dentro de ese ámbito. En la función Index, se agrega un cliente, usando la función AddEntity.

La interfaz Jaguar.DataAccess.IRepository contiene la lista de todas las funciones.

Recomendaciones

En conclusión, EntityFrameworkCore viene mejorando mucho en rendimiento y compatibilidad con diferentes proveedores. Utilizar un patrón de repositorio genéricos se vuelve aún más importante. Independientemente si se utiliza el repositorio genérico descrito aquí, así como cualquier otro, es importante adquirir la práctica de hacerlo bajo ese patrón.

Comments

Dejar una contestacion

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *