EF Core 10 Migrations are the standard way to evolve a database schema in lockstep with your .NET 10 model. Instead of hand-writing CREATE TABLE and ALTER TABLE statements, you define entities in C#, run one command, and EF Core generates an exact, reviewable set of schema changes. Run the same workflow on staging and production and you get the same schema every time, which is exactly what a repeatable deploy pipeline needs.
This guide walks the entire lifecycle of EF Core 10 Migrations, from creating your first migration to deploying it against a production database. You will learn what the Migrations folder really contains, how the model snapshot drives every diff, and why a generated SQL script is the professional way to ship a schema. The examples use .NET 10 and EF Core 10, but the workflow transfers to any modern EF Core project.
EF Core 10 Migrations from the Command Line
Everything starts with the dotnet-ef global tool. EF Core 10 ships with the .NET 10 SDK, but the command-line tools are installed separately. Once installed, three commands cover most of your daily work: add, update, and script.
dotnet tool install --global dotnet-ef
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet ef migrations add AddOrdersTable
dotnet ef database update
Each command has a precise job. dotnet ef migrations add AddOrdersTable compares your current C# model with the last migration in history, computes the difference, and writes a new timestamped migration plus an updated model snapshot. dotnet ef database update then executes every pending migration against the database named in your connection string. If you prefer to review before you apply, dotnet ef migrations script produces the SQL without touching a database.
How the EF Core 10 Migrations Folder Is Organized
Migrations live in a Migrations folder inside the project that owns your DbContext. A single migration is actually three files, and knowing what each one does removes most of the mystery around EF Core 10 Migrations:
- xxxx_AddOrdersTable.cs — the migration itself, with Up() and Down() methods containing the schema operations.
- xxxx_AddOrdersTable.Designer.cs — metadata that records the state of the model at this point in history.
- AppDbContextModelSnapshot.cs — a complete snapshot of the current model that EF Core compares against on every future diff.
The snapshot is the engine of EF Core 10 Migrations. EF Core never compares your entities directly to the live database; it compares your entities to the snapshot, and the difference becomes the next migration. That is why the snapshot file must never be edited by hand, and why you should treat every migration as append-only once it has been applied anywhere outside your machine. Before you add a new one, run dotnet ef migrations list to see which migrations exist, which environments applied them, and which are still pending.
Applying EF Core 10 Migrations to a Database
When you run the add command, EF Core writes the migration for you. Here is what a generated Up() method looks like for a simple Orders table:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
Id = table.Column<Guid>(type: "uuid", nullable: false),
CustomerName = table.Column<string>(type: "text", nullable: false),
Total = table.Column<decimal>(type: "numeric", nullable: false)
},
constraints: table => table.PrimaryKey("PK_Orders", x => x.Id));
}
Read the migration like a recipe: create this table, add these columns, build this primary key. Because the file is plain C#, it can be reviewed in a pull request exactly like any other code. If something is missing — an index for a frequently filtered column, a default value, a check constraint — this is the moment to add it with migrationBuilder.Sql() or a column annotation, before the migration ever touches a real database.
Deploying EF Core 10 Migrations
Development databases are forgiving; production databases are not. Running dotnet ef database update on a production server means installing the CLI tool, restoring design-time packages, and handing a developer account write access to the database — none of which belong in a deploy. The safer path is to generate a SQL script and run it with your normal database tooling.
dotnet ef migrations script --from 0 --to latest --output deploy.sql
The generated script contains every migration in order, wrapped in transactions, and is fully self-contained. Your operations team can review it, run it during a maintenance window, and keep an audit trail of exactly what changed. That is the difference between "someone ran update locally" and a schema deploy you can reproduce and defend.
One refinement worth adopting early is a design-time factory. When the dotnet-ef tool needs to build your model — for migrations, scripts, or scaffolding — it first looks for a class implementing IDesignTimeDbContextFactory<AppDbContext>. Without one, EF Core falls back to the application host builder, which can fail if startup code touches a database that does not exist yet or requires services that are not registered. A dedicated factory keeps the tool chain independent from the runtime, so a fresh checkout can generate migrations without ever starting the application.
Key Takeaways
- Create migrations with
dotnet ef migrations addand apply them withdotnet ef database update. - Every migration is three files: the migration, its designer metadata, and the model snapshot.
- The snapshot is the source of truth for diffs; never edit it by hand.
- Review generated migrations like code, and add custom SQL where conventions fall short.
- For production, generate a SQL script instead of running the CLI against a live database.
FAQ
Do I need EF Core 10 Migrations if I already call EnsureCreated?
EnsureCreated builds a schema from the model but records no history. The next model change has no starting point, which makes it fine for prototypes and useless for any schema that will evolve. Migrations exist exactly to solve that.
Can I apply EF Core 10 Migrations without the dotnet-ef tool?
Yes — the migrations themselves are just C#. You can apply them at startup with context.Database.MigrateAsync(), or better, generate a SQL script and run it in your deploy step.
What happens to the database when I edit a migration that already shipped?
The model snapshot no longer matches environments that applied the old version, and the next migration will try to redo changes. Never edit a shipped migration; add a new one that fixes the schema instead.
Where can I see EF Core 10 Migrations in a real production project?
Every Indotalent product ships its complete .NET 10 source code, including a full EF Core 10 schema and migration history, for $21 each.