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