Introduction

EF Core maintains a model snapshot that represents the expected database schema. When your entity configuration changes (new properties, renamed columns, relationship changes) but no migration has been created, EF Core detects the mismatch and throws an error. In development, this is a helpful safeguard. In production, it can block application startup.

Symptoms

  • System.InvalidOperationException: The model backing the context has changed
  • There are pending model changes. Apply the migrations before running the application
  • Application works locally but fails on deployed database
  • Error after adding a new property to an entity
  • dotnet ef database update succeeds but error persists

Example error: ``` System.InvalidOperationException: The model for context 'AppDbContext' has changed since the last migration was applied. Consider applying a new migration.

Current model snapshot differs from the current model. Added: Property User.TwoFactorEnabled Modified: Property Order.Status (type changed) ```

Common Causes

  • Entity property added or modified without creating a migration
  • Migration created but not applied to the target database
  • Manual database changes not reflected in migrations
  • Model snapshot out of sync with migration files
  • Deploying code changes without deploying corresponding migrations

Step-by-Step Fix

  1. 1.Create and apply the migration:
  2. 2.```bash
  3. 3.# Create a new migration for the model changes
  4. 4.dotnet ef migrations add AddTwoFactorEnabledToUser

# Review the generated migration cat Migrations/<timestamp>_AddTwoFactorEnabledToUser.cs

# Apply to the database dotnet ef database update ```

  1. 1.Check pending migrations:
  2. 2.```bash
  3. 3.# List all migrations and their status
  4. 4.dotnet ef migrations list

# Check which migrations have been applied dotnet ef database update --dry-run ```

  1. 1.Apply migrations programmatically at startup:
  2. 2.```csharp
  3. 3.var builder = WebApplication.CreateBuilder(args);
  4. 4.builder.Services.AddDbContext<AppDbContext>(options =>
  5. 5.options.UseSqlServer(builder.Configuration.GetConnectionString("Default")));

var app = builder.Build();

// Apply pending migrations at startup (development only) if (app.Environment.IsDevelopment()) { using var scope = app.Services.CreateScope(); var context = scope.ServiceProvider.GetRequiredService<AppDbContext>(); context.Database.Migrate(); }

app.Run(); ```

  1. 1.Generate SQL script for production deployment:
  2. 2.```bash
  3. 3.# Generate a SQL script for DBA review
  4. 4.dotnet ef migrations script --output migrations.sql

# Generate script from specific migration to latest dotnet ef migrations script AddTwoFactorEnabled --output migrations.sql

# For idempotent script (safe to run multiple times) dotnet ef migrations script --idempotent --output migrations.sql ```

  1. 1.Handle model mismatch without migration:
  2. 2.```csharp
  3. 3.// If you want to ignore model changes (not recommended for production)
  4. 4.builder.Services.AddDbContext<AppDbContext>(options =>
  5. 5.options.UseSqlServer(connectionString, sql =>
  6. 6.{
  7. 7.sql.MigrationsAssembly("MyApp.Data");
  8. 8.// Disable model validation (development only)
  9. 9.sql.EnableRetryOnFailure();
  10. 10.})
  11. 11.// Suppress the model validation error
  12. 12..ConfigureWarnings(warnings =>
  13. 13.warnings.Ignore(CoreEventId.ModelValidationWarning)));
  14. 14.`

Prevention

  • Always create a migration after changing entity configuration
  • Run dotnet ef migrations list before deploying to check for pending changes
  • Include migration step in your CI/CD pipeline
  • Use context.Database.Migrate() in development, SQL scripts in production
  • Never manually modify the database schema without creating a migration
  • Add a CI check that verifies no model differences: dotnet ef migrations has-pending-model-changes