Skip to main content

Database Update

Lagoon relies on Entity Framework Core with a code-first approach: the C# model describes the expected structure, then EF Core generates migrations to evolve the database schema.

Application DbContext​

The EF Core context for the application is typically named ApplicationDbContext and is found in the Model project. In the demonstration solution, it is located at Apps\Demo\Model\Context\ApplicationDbContext.cs.

The choice of base class depends on the key type and the need for change tracking:

Base classUsage
LgApplicationDbContext<TUser>Context with string keys.
LgApplicationDbContextGuid<TUser>Context with Guid keys.
LgApplicationTrackedChangeDbContext<TUser>Context with string keys and audit trail.
LgApplicationTrackedChangeDbContextGuid<TUser>Context with Guid keys and audit trail.

The demonstration uses LgApplicationDbContextGuid<ApplicationUser>. The DbContext configures the EF Core provider, the migrations assembly, OpenIddict, Identity rules, roles, and date conventions.

Create a migration​

A migration captures the evolution of the EF Core model. For the first release, the previous documentation uses the name InitialCreate:

dotnet ef migrations add InitialCreate

For subsequent releases, create a new migration with a descriptive name:

dotnet ef migrations add <Name>

Lagoon conventions require class names in PascalCase, for example Init, AddTableTrackedChanges, or LastLoginDate. The demonstration solution contains an actual migration named Init, generated in Apps\Demo\Model\Migrations\20230412074341_Init.cs.

Migrations are placed under Apps\*\Model\Migrations\. The generated EF Core snapshot is called ApplicationDbContextModelSnapshot.cs.

To explicitly target EF Core projects, use the Model project and the Server startup project:

dotnet ef migrations add <Name> --project Model\APP.Model.csproj --startup-project Server\APP.Server.csproj

Apply in development​

In development, apply migrations with:

dotnet ef database update

With explicitly targeted projects:

dotnet ef database update --project Model\APP.Model.csproj --startup-project Server\APP.Server.csproj

Database update on application startup​

By default, the database is updated automatically on application startup. When the configuration allows it, the server Main class calls UpdateDatabaseAsync before calling the OnStartAsync method. This method applies pending migrations and then calls OnUpdateDatabaseAsync.

OnUpdateDatabaseAsync is used to initialize data. In the demonstration, it calls DataSeeder.SeedAsync(...) and then FakeDataSeeder.SeedAsync(...) in development.

protected virtual async Task InternalStartAsync(IServiceProvider scopedServiceProvider, CancellationToken cancellationToken)
{
if (Configuration.GetValue("Lagoon:AutoUpdateDatabase", true))
{
// Applies pending migrations and then triggers OnUpdateDatabaseAsync.
await UpdateDatabaseAsync(scopedServiceProvider, cancellationToken);
}
}

This automatic update can be disabled from appsettings.json by setting Lagoon:AutoUpdateDatabase to false:

{
"Lagoon": {
"AutoUpdateDatabase": false
}
}
Multiple instances in parallel

Disable Lagoon:AutoUpdateDatabase as soon as multiple instances of the application start in parallel (load balancing, multiple containers, …). Without this precaution, each instance would try to apply migrations at the same time on startup.

Prepare a production database update​

Several modes for updating the database are available for production:

ModeDescription
Automatic on startupDefault behavior, see above.
Command lineExecuting the updateDB command from the server, without restarting the application.
SQL scriptScript generated in advance and executed manually, according to your environment's operational process.

Command line​

The Batch application in the solution declares the updateDB command (see Lagoon console applications). From the server, execute:

monapp updateDB

This command applies pending migrations without starting the web server, allowing you to prepare the database before or independently of the deployment.

SQL script generated in advance​

For a production database, generate a SQL script from the migrations:

dotnet ef migrations script

Have this script validated and executed according to your environment's operational process (for example by a DBA team without access to the .NET SDK).

EF Core documentation​