Migraciones automáticas con Entity Framework Core Code First
Cómo mantener la BD de tu API siempre sincronizada cuando utilizas EF Code first? Apréndelo aquí 🐿️🙌

Conceptos previos

Como ya sabrás Entity Framework Core es un ORM que te permite trabajar con bases de datos de manera más intuitiva y eficiente, usando código en lugar de consultas SQL directas.

Tiene 3 enfoques o maneras de usarlo:

  • Code first
  • Database first
  • Model first

El enfoque Code First es el enfoque mas popular, y aquí defines primero las clases y sus relaciones en código, y luego Entity Framework genera automáticamente la estructura de la base de datos basada en esas clases mediante un proceso llamado Migración.

El flujo común bajo el enfoque Code First es:

  1. Definir/cambiar modelos: Creas tus clases C# como representaciones de las tablas de la base de datos o modificas dichas clases.
  2. Generar migraciones: Ejecutas el comando add-Migration, que genera un archivo que describe cómo cambiar la base de datos para que coincida con el nuevo modelo.
  3. Aplicar migraciones: Con update-Database, aplicas esas migraciones para actualizar la base de datos sin perder datos existentes.

Migraciones automáticas

Son una característica de Entity Framework que actualiza automáticamente la base de datos cuando cambias las clases (entidades o modelos) de tu aplicación. En vez de escribir SQL manualmente o ejecutar un comando para ejecutar la última migración a tu base de datos, el sistema detecta los cambios y ajusta la base de datos por ti, como crear nuevas tablas o modificar columnas, sin intervención manual. Esto suele ser útil en desarrollo para mantener la base de datos al día con el código, o en un ambiente utilizado para entornos locales como docker, sin embargo no es común usarlas en producción porque podrían causar problemas inesperados.

En el enfoque Code First, las migraciones automáticas pueden ser útiles en desarrollo para hacer que la base de datos se mantenga al día sin intervención manual. Pero en producción, las migraciones manuales y controladas son preferidas para tener más control y evitar problemas inesperados.

Cómo aplicarlas en mi API RESTful de .NET

Es sencillo, tienes que actualizar tu clase Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("defaultConnection"));
});
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();
if (app.Environment.IsDevelopment() || app.Environment.EnvironmentName.Equals("Docker"))
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

if (app.Environment.IsDevelopment() || app.Environment.EnvironmentName.Equals("Docker"))//Sólo en ambiente development o docker
{
    await ApplyMigrationsAndSeedDataAsync(app);//migraciones automáticas
}
app.Run();

static async Task ApplyMigrationsAndSeedDataAsync(WebApplication app)
{
    using var scope = app.Services.CreateScope();
    var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();

    if (dbContext.Database.GetPendingMigrations().Any()) //Sólo cuando haya migraciones pendientes
    {
        await dbContext.Database.MigrateAsync();
    }
}

En aplicaciones de tipo Web API hechas con .NET 5 o versiones anteriores de .NET Core esta modificación iría en Startup.cs

Entonces ahora cuando ejecutes tu API si hay migraciones pendientes estas se ejecutarán contra la base de datos automáticamente al iniciar la aplicación, tendrás algo así:

Y bien eso es todo estimado dev! Para trabajar en el ambiente de desarrollo esto viene muy bien.

En el ambiente de producción no es común que se hagan migraciones automaticas, al menos no es una buena práctica (aunque sí que se da muchas veces hoy por hoy pero ese es otro tema xd)

En producción lo que hacen muchas organizaciones es implementar CI/CD (Integración Continua/Despliegue Continuo), donde las migraciones se ejecutan automáticamente como parte del flujo de trabajo de despliegue mediante scripts, garantizando que los cambios en la base de datos se gestionen de manera segura y sistemática.

Si compartes esta entrada serás un dev feliz 🥳. Foto de Brooke Cagle en Unsplash

Si esta entrada te ha gustado, compártela genio 🐿️😉

Créditos de imagen de portada: Foto de Homa Appliances en Unsplash

Deja una respuesta

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