100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C#

Applying and Reverting Migrations

How to apply pending migrations to a database, generate deployable SQL scripts, and safely roll back schema changes.

MigrationsBeginner8 min readJul 10, 2026
Analogies

Applying Migrations to a Database

dotnet ef database update applies pending migrations in order by executing each unapplied migration's Up() method against the target database, then records each applied migration's ID in the __EFMigrationsHistory table so EF Core knows exactly which ones have already run. You can also apply migrations programmatically at startup by calling context.Database.Migrate(), though this is discouraged in production because it couples the application's startup to schema changes and can race when multiple instances start simultaneously.

🏏

Cricket analogy: It's like a groundsman working through a checklist of pitch preparations for the next Test, ticking off each task in the official log so no one repeats or skips a step across match days.

Generating Idempotent SQL Scripts

For production deployments, dotnet ef migrations script --idempotent generates a single .sql file wrapped in conditional checks against the __EFMigrationsHistory table, so it can be run safely even if some of the migrations it contains were already applied. This decouples deployment — typically a DBA or a CI/CD pipeline running the script with elevated database credentials — from the application's own runtime, since the app never needs ALTER TABLE permissions itself.

🏏

Cricket analogy: It's like a substitute umpire being handed a full set of match instructions that each say 'only apply if not already actioned,' so stepping in mid-match never repeats a decision already made.

bash
# Generate an idempotent SQL script from the beginning through the latest migration
dotnet ef migrations script --idempotent -o deploy/migrate.sql

# Excerpt of the generated script's guard pattern:
# IF NOT EXISTS (SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20260710120000_AddOrdersTable')
# BEGIN
#     CREATE TABLE [Orders] (...)
#     INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
#     VALUES (N'20260710120000_AddOrdersTable', N'8.0.4')
# END

Reverting Migrations

dotnet ef database update <PreviousMigrationName> rolls a database back by executing the Down() methods of every migration applied after the target, in reverse order, and removing their rows from __EFMigrationsHistory. Separately, dotnet ef migrations remove deletes the most recently added migration file and reverts the ModelSnapshot to its prior state, but this only works safely for migrations that haven't yet been applied to a shared database.

🏏

Cricket analogy: It's like a third umpire overturning a series of on-field calls one by one in reverse order after a review, restoring the scorecard exactly to its state before the disputed sequence began.

Down() methods can be destructive: an AddColumn's Down() typically calls DropColumn, which permanently deletes any data stored in that column. Not all changes are cleanly reversible either — a Down() that drops a table cannot recover data that was inserted after the corresponding Up() ran. Always back up production data before reverting, and treat migrations.remove as safe only for migrations that have never touched a shared database.

  • dotnet ef database update applies pending Up() methods in order and records progress in __EFMigrationsHistory.
  • context.Database.Migrate() at app startup is convenient locally but risky in production due to race conditions.
  • migrations script --idempotent produces a deployable SQL file safe to run even if partially applied already.
  • Idempotent scripts decouple schema deployment from application deployment.
  • database update <name> reverts by running Down() methods in reverse order.
  • migrations remove only safely deletes unapplied migrations, not ones already run against a shared database.
  • Down() operations can be destructive and are not guaranteed to be fully reversible without data loss.

Practice what you learned

Was this page helpful?

Topics covered

#EntityFrameworkCoreStudyNotes#MicrosoftTechnologies#ApplyingAndRevertingMigrations#Applying#Reverting#Migrations#Database#StudyNotes#SkillVeris#ExamPrep