A database migration is a named, timestamped record of a schema change. For a SQL-backed application, migrations provide a way to update table structure as application versions change. The database records which migrations it has received, so a later deployment applies only the outstanding changes, in order. section 9.1.3
In an Aspire-hosted online shop, the API service depends on a SQL database. Configure migrations as part of deployment so a new application version can bring its database schema up to date automatically. Plan this alongside availability: the deployment setup is intended to apply changes without downtime. section 9.1 section 9.1.3
To establish the migration workflow:
- Add Microsoft.EntityFrameworkCore.Design to the API service. Ensure an Entity Framework database context and at least one entity type exist, and install the Entity Framework CLI tools. section 9.1.3
- Generate an initial migration with `dotnet ef migrations add InitialCreate`. On first deployment, its schema is applied and its name is recorded by the database. section 9.1.3
- After changing an entity, generate another migration. For example, adding an optional address to an order and running `dotnet ef migrations add AddOrderAddress` produces a migration that adds a nullable column to `Orders`. section 9.1.3
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "Address",
table: "Orders",
type: "nvarchar(max)",
nullable: true);
}
The generated `Up` method shows the database operation behind the order-address change: it adds a nullable `Address` column to `Orders`. section 9.1.3
To run outstanding migrations when the service starts, a hosted `DataSeederService` creates a dependency-injection scope, resolves `ProductsDbContext`, and calls a migration method before seeding data. That method uses the database execution strategy to call `MigrateAsync`. section 9.1.3
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using var scope = _serviceProvider.CreateScope();
using var context = scope.ServiceProvider.GetRequiredService<ProductsDbContext>();
await RunMigrationAsync(context, stoppingToken);
SeedData(context);
}
The hosted-service flow resolves the database context, runs migrations, then seeds product data. section 9.1.3
Do not assume migrations will work on a database created with `EnsureCreated()`. That path does not create the table used to track migration versions; the database needs manual changes before migrations can update it. section 9.1.3
