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 class | Usage |
|---|---|
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
}
}
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:
| Mode | Description |
|---|---|
| Automatic on startup | Default behavior, see above. |
| Command line | Executing the updateDB command from the server, without restarting the application. |
| SQL script | Script 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).