Lagoon EF Core contexts
Lagoon provides EF Core base classes that integrate ASP.NET Identity, the framework's internal entities, and application conventions. The application context is usually named ApplicationDbContext and lives in the Model project.
Choosing the base class
The choice depends first on the Identity key type, then on whether change tracking is needed.
| Base class | User/role key type | Change tracking | User constraint |
|---|---|---|---|
LgApplicationDbContext<TUser> | string | No | TUser inherits from LgIdentityUser |
LgApplicationDbContextGuid<TUser> | Guid | No | TUser inherits from LgIdentityUserGuid |
LgApplicationTrackedChangeDbContext<TUser> | string | Yes | TUser inherits from LgIdentityUser |
LgApplicationTrackedChangeDbContextGuid<TUser> | Guid | Yes | TUser inherits from LgIdentityUserGuid |
LgApplicationDbContextBase<TUser, TRole, TKey> inherits from IdentityDbContext<TUser, TRole, TKey>, implements ILgApplicationDbContext, and exposes common members such as Database, Eulas, SaveChangesAsync(...), Set<TEntity>(), and LoadAnonymizerRules().
Guid keysRecent Lagoon applications often use LgApplicationDbContextGuid<TUser> to work directly with Guid identifiers on the Identity side.
Structure of the application context
A Lagoon context configures the EF Core provider in a static Configure(...) method, calls the inherited configuration in OnModelCreating(...), then adds project-specific rules.
public class ApplicationDbContext : LgApplicationDbContextGuid<ApplicationUser>
{
internal protected const string CONNECTION_STRING_KEY = "SqliteDb";
public ApplicationDbContext(DbContextOptions options)
: base(options)
{ }
public ApplicationDbContext()
{ }
public static void Configure(DbContextOptionsBuilder builder, IConfiguration configuration, bool enableDetailedLogging = false)
{
// Configure le fournisseur EF Core et l'assembly qui contient les migrations.
builder.UseSqlite(
configuration.GetConnectionString(CONNECTION_STRING_KEY),
options => options.MigrationsAssembly(GetAssemblyName<ApplicationDbContext>()));
// Enregistre les jeux d'entités nécessaires à OpenIddict avec des clés Guid.
builder.UseOpenIddict<Guid>();
if (enableDetailedLogging)
{
// Active les détails utiles pendant les migrations et le diagnostic local.
builder.EnableDetailedErrors();
builder.EnableSensitiveDataLogging();
}
}
protected override void OnModelCreating(ModelBuilder builder)
{
// La configuration Lagoon/Identity doit être appliquée avant les règles projet.
base.OnModelCreating(builder);
SetUserNameRequired(builder);
SetUserEmailRequired(builder);
DisableCascadingDeletionBehavior(builder);
HasIdentityRoles<Roles>(builder);
}
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
base.ConfigureConventions(configurationBuilder);
// Enregistre les dates en UTC et les recharge en heure locale.
configurationBuilder.DateSaveAsUtcLoadAsLocal();
}
}
UseOpenIddict<Guid>() is mandatorySince Lagoon 4.0, OpenIddict entities always use a Guid primary key, regardless of the key type of ApplicationUser: an ApplicationUser : LgIdentityUser (string key) must also declare builder.UseOpenIddict<Guid>().
The server hard-codes this key type; a builder.UseOpenIddict() call without an argument (string key) makes the application startup fail with InvalidOperationException: Cannot create a DbSet for 'OpenIddictEntityFrameworkCoreApplication'.
The lgn update upgrade automatically rewrites the call and generates the corresponding EF migration. Review this migration before applying it: the string → Guid conversion empties the OpenIddict tables (tokens and authorizations are regenerated on sign-in, applications and scopes are reseeded at startup) and, on SQL Server, drops and recreates the primary keys, foreign keys, and indexes carried by the converted columns.
Useful Lagoon methods in OnModelCreating
| Method | Role |
|---|---|
SetUserNameRequired(builder) | Makes UserName and NormalizedUserName required on the Identity user. |
SetUserEmailRequired(builder) | Makes Email and NormalizedEmail required on the Identity user. |
DisableCascadingDeletionBehavior(builder) | Forces EF Core relationships to DeleteBehavior.NoAction. |
HasIdentityRoles<TAppRole>(builder) | Adds Identity roles from an enumeration. |
UseNotifications<TNotification>(builder, ...) | Declares the notification and user-association tables. |
base.OnModelCreating(builder) must remain the first call: it configures Identity, LgSettings, Eulas, the optional collation, and Lagoon's internal entities.
The ILgApplicationDbContext interface
ILgApplicationDbContext is the common contract used by dependency injection. It notably exposes:
| Member | Usage |
|---|---|
Database | Access to core EF Core operations. |
Eulas | Table of terms of use managed by Lagoon. |
SaveChanges() / SaveChangesAsync(...) | EF Core persistence. |
Set<TEntity>() | Generic access to a DbSet<TEntity>. |
LoadAnonymizerRules() | Anonymization rules used by database exports. |
Change tracking
To enable the EF Core audit trail, the context inherits from an LgApplicationTrackedChangeDbContext... variant. Changes are written to the LgTrackedChanges table for tracked entities.
public class ApplicationDbContext : LgApplicationTrackedChangeDbContextGuid<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor)
: base(options, httpContextAccessor)
{ }
}
Tracking is driven by the EnableTrackedChangeAttribute and TrackedChangeAttribute attributes. The tracked variants also add SaveChangesAsync(string actionDetails, CancellationToken cancellationToken = default) and the TrackedChangeDisabled property.
Do not add a DbSet<TrackedChange> or DbSet<TrackedChangeGuid> manually: the LgApplicationTrackedChangeDbContext<TUser> and LgApplicationTrackedChangeDbContextGuid<TUser> contexts already declare the audit entity.
Model conventions
| Element | Convention |
|---|---|
| Entity class | Singular name. |
DbSet | Plural name. |
| Primary key | Never nullable. |
| String | Define a maximum length. |
| Boolean | Is prefix. |
| Date | Date suffix. |
| Navigation | virtual property. |
| Migration snapshot | Never edit ApplicationDbContextModelSnapshot.cs by hand. |