What are migration strategies in EF Core?

4 minintermediateEF-Coremigrationsschema

Quick Answer

Migrations track model changes and apply them to the database schema incrementally. Core commands: `Add-Migration`/`dotnet ef migrations add` to create one, `Update-Database`/`dotnet ef database update` to apply, and `Script-Migration` to generate SQL for controlled deployments. Strategies include applying migrations in CI/CD via SQL scripts (recommended for production) rather than `Migrate()` at startup, and keeping migrations small and reviewed.

Detailed Answer

Migrations track changes to your data model and update the database schema.

1. Basic Migration Commands:

# Add a new migration
dotnet ef migrations add MigrationName

# Update database to latest migration
dotnet ef database update

# Update to specific migration
dotnet ef database update MigrationName

# Remove last migration (if not applied)
dotnet ef migrations remove

# Generate SQL script
dotnet ef migrations script

# List all migrations
dotnet ef migrations list

2. Migration Strategies:

A. Automatic Migrations (Development)

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();
    
    using (var scope = host.Services.CreateScope())
    {
        var context = scope.ServiceProvider.GetRequiredService();
        context.Database.Migrate(); // Apply pending migrations
    }
    
    host.Run();
}

B. Manual SQL Scripts (Production)

# Generate SQL script for deployment
dotnet ef migrations script --idempotent --output migration.sql

C. Custom Migration Code

public partial class AddProductIndex : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateIndex(
            name: "IX_Products_Name",
            table: "Products",
            column: "Name");
            
        // Custom SQL
        migrationBuilder.Sql(@"
            UPDATE Products 
            SET Price = Price * 1.1 
            WHERE CategoryId = 1
        ");
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropIndex(
            name: "IX_Products_Name",
            table: "Products");
    }
}

D. Data Seeding in Migrations

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.InsertData(
        table: "Categories",
        columns: new[] { "Id", "Name" },
        values: new object[,]
        {
            { 1, "Electronics" },
            { 2, "Books" },
            { 3, "Clothing" }
        });
}

Best Practices:

  • Keep migrations small and focused
  • Test migrations in development first
  • Use --idempotent scripts for production
  • Never modify applied migrations
  • Keep migration history in source control

Related Resources