Este fin de semana hemos estado en lo que ya es una cita ineludible para los desarrolladores: DotNet Málaga, donde nuestros compañeros Elena Guzmán y Alberto Picazo ofrecieron una charla sobre Entity Framework.
Elena comenzó con una pregunta a los asistentes, que se solucionaría más adelante: ¿Qué es Lazy Loading? Por medio de un QR, los asistentes tuvieron que responder entre tres opciones: Relación entre entidades, carga a demanda de datos o carga de relaciones. ¿Quieres saber la respuesta? Te toca seguir leyendo ?
Tras esta pregunta abierta al público, Elena comenzó a explicar qué es Entity Framework: un ORM (object-relational mapper) para el ecosistema .NET. Más concretamente, Entity Framework Core permite el acceso a los datos a través de modelos. Estos modelos reúnen la Clase que representa la entidad y un contexto que representa la conexión a base de datos, permitiendo así almacenar y acceder a los datos a través de consultas.
Además, en la reciente .Net Conf celebrada entre el 23 y el 25 de septiembre, se presentó Entity Framework Core 3.0, del que podéis conocer sus novedades en este enlace.
Una vez presentado, Elena explicó las dos maneras de enfrentarse a la base de datos: Code First y DataBase First. Mientras que en la primera no se cuentan con datos, por lo que se deben crear las Clases que definirán las entidades en la base de datos; en la segunda opción se cuenta con una base de datos ya existente, por lo que se deben generar las Clases y el contexto que permitirán acceder a las entidades a través de EntityFramework.
Elena quiso profundizar en el contexto antes de continuar con las entidades; una de las clases más importantes de Entity Framework. El contexto representa una conexión a la base de datos, además de su configuración. Gracias a ella, se pueden realizar operaciones CRUD con la base de datos. Y…¿cómo se aplica? Tan solo habrá que crear una clase que herede de DB Context, desde donde se almacenarán todos los datasets. Además, el contexto también nos permite modelar nuestras entidades y cómo se relacionan entre ellas a través de ModelBuilder.
¿Cómo configurar Entity Framework?
- Instalar los paquetes Nuget para EntityFramework.
- EntityFrameworkCore.
- EntityFrameworkCore.Tools, que añade unos comandos para facilitar el uso de migraciones.
- EntityFrameworkCore dedicado al proveedor de bases de datos:
Una vez hecho esto, se creará una Clase que hereda de DbContext para personalizarla, y, por último, Entity Framework Core, se configura en la Clase Startup con la siguiente línea:
Con estos pasos, la API ya apunta a la base de datos con la que vamos a trabajar.
Una vez hecho esto, llega el momento de crear las entidades, con todas las propiedades que necesitemos:
- Relacionaremos estas entidades (si es necesario) a través de los métodos DataAnnotation, FluentAPI ¡o ambos!
Dependiendo de la metodología que utilicemos, habrá que llevar a cabo diferentes pasos:
- Si trabajamos en CodeFirst crearemos la primera migración, y ejecutamos.
- Si trabajamos con DatabaseFirst haremos un scaffolding de la base de datos.
De esta manera, ya estamos listos para, a través del contexto, hacer consultas y modificar datos.
Migraciones
Tras esta explicación, Elena volvió a las migraciones para profundizar en este concepto. Son la forma en la que se generan cambios en nuestra base de datos, ya que siempre son muy susceptibles a cambios. Entity Framework se basa en detectar los cambios que se hacen en las entidades para poder generarlos. Cada vez que se produce un cambio en estas entidades, se puede generar una migración que aplicará esos cambios en la base de datos con la que se está trabajando.
Las migraciones tienen una alta importancia, por lo que existe una seria de buenas prácticas recomendadas por Microsoft:
- Cada miembro debe tener una base de datos local para desarrollo.
- Evitar migraciones automáticas.
- Una sola persona encargada de las migraciones.
Las migraciones están divididas en dos partes:
- Método Up(): Incluye el código que se va a ejecutar sobre la base de datos para cambiarla.
- Método Down(): Todos los pasos que ha de realizar para revertir el cambio y dejarlo en el estado anterior a la migración.
Con las migraciones podemos:
- Cambiar entidades.
- Actualizar relaciones que ya existen.
- Introducir datos en tablas maestras.
- Introducir datos en otras tablas ya conectadas.
Actualización de bases de datos
Una vez terminada la migración, se debe aplicar de forma explícita en la base de datos. Por una parte, en el caso de tener acceso directo a la base de datos, se puede ejecutar en Package Manager Console update-database, que, en el caso de estar hecha de manera correcta, generará los cambios en la base de datos.
Por el contrario, si no contamos con acceso a la base de datos, podemos generar un script que pasar al DBA, para que se ejecuten los cambios a través de él a través de la ejecución del siguiente comando: script-migration –idempotent, que generará un script en SQL con todos los cambios que han de realizarse en esa migración. De esta manera, la persona encargada de gestionar esta base de datos deberá aplicarle el script para generar esos cambios.
Entidades
Una vez explicados los conceptos básicos, llegó el momento de conocer las diferentes entidades:
- Data Annotation. Consiste en añadir una serie de anotaciones que describe qué papel va a jugar en la base de datos, como por ejemplo:
- [Key] será la propiedad que haga de Primary Key.
- [Required] será una propiedad necesaria.
- [ForeignKey(“NombrePropiedad”)] marcará una Foreign Key, junto con el nombre de la propiedad a la que se refiere como clave ajena.
- [MaxLength] marca un máximo de longitud en la cadena de texto o array de bytes.
*Consulta el ejemplo de Data Annotation en el minuto 18:00 del vídeo de la parte inferior del post*
- Fluent API. Consiste en describir cómo se van a compartar las entidades sobre la tabla. Usando la Clase DbModelBuilder, permite configurar nuestras entidades con muchas posibilidades, más allá de los atributos de DataAnnotation. Esta entidad no es excluyente, ya que podemos definir entidades con DataAnnotation junto con FluentAPI, dependiendo de nuestras necesidades:
- HasKey() es un método que marcará una propiedad como Primary Key
- Property() recibe una propiedad que se puede modificar con:
- IsRequired() indica obligatoriedad de la propiedad.
- HasForeignKey() indica una Foreign Key.
Estos dos métodos no son excluyentes, por lo que las tablas se podrán definir combinando ambos métodos.
*Consulta el ejemplo de Fluent API en el minuto 20:00 del vídeo de la parte inferior del post*
Buenas prácticas
Tras presentar las entidades, Elena presentó las buenas prácticas del uso de Entity Framework:
- IQueryable. Permite generar consultas para cargar datos y solo materializarlos en el momento en el que se necesiten, ayudando a tener un código más limpio. Es la interfaz que nos permite realizar consultas a conjuntos de datos. Permiten evaluar la consulta, por compleja que sea, para determinar qué tipo de dato es el que se obtiene al final de la misma.
- Eager loading. Consiste en la carga de datos para traer consigo datos relacionados. Se conoce también como carga ansiosa o inclusiva.
- Lazy Loading. Es el método opuesto al concepto anterior, eager loading. Cuando existen datos relacionados, también llamada carga perezosa accede a estos solo cuando son invocados. Podemos activarla/desactivarla en nuestro contexto. ¡Ya tenéis la respuesta a la pregunta del inicio!
Demos
Elena finalizó con una demo de Entity Framework, en la que utilizó una aplicación Blazor y utilizó Entity Framework para gestionar a los personajes de rol.
*Consulta la demo en el minuto 24:40 del vídeo de la parte inferior*
Tras esta demo, llegó el turno de Alberto Picazo, que explicó cómo realizar un despliegue de una migración con Entity Framework en Azure DevOps. Muchos de los asistentes no estaban familiarizados con la herramienta Azure DevOps, por lo que Alberto hizo una pequeña explicación: es la herramienta que proporciona Microsoft para hacer integración continua y despliegues automáticos.
Muchas veces, al comenzar un proyecto surge la siguiente pregunta: Usamos Entity Framework, migraciones…pero ¿cómo meterlo en un pipeline con Azure DevOps? En eso consiste la demo de Alberto Picazo.
Consulta la demo en el minuto 34:10 del vídeo de la parte inferior*
Después de la charla, solo nos quedó disfrutar del resto de ponencias con nuestros compañeros, y despedirnos hasta el año que viene, ¡donde seguro que volveremos!