Documentation

fsds/db-manager-seeding-error-fix.md

Fix Database Manager Seeding Errors

Problem Summary

After redeployment, the Database Manager (db-manager) is failing during the seeding phase for core-data with the error:

DbContext must have tenant scope set before saving changes.
Call SetTenantId(Guid) for tenant operations or SetSystemScope(SystemScopeReason) for system operations.

Root Cause

The CoreDataReferenceDataSeeder is missing the required ISystemDbContextUser marker interface and the SetSystemScope() call that other seeders have. This is a code bug introduced when the tenant scope validation was added to DynaplexDbContext.

Evidence:

  • IdentityReferenceDataSeeder and SpatialReferenceDataSeeder both have:
    • ISystemDbContextUser interface implemented
    • db.SetSystemScope(SystemScopeReason.Seeding); call at start of SeedAsync
  • CoreDataReferenceDataSeeder is missing both of these

Solution

Add the missing ISystemDbContextUser interface and SetSystemScope() call to three seeders:

  1. CoreDataReferenceDataSeeder - calls SaveChangesAsync, will fail without fix
  2. PrismReferenceDataSeeder - calls SaveChangesAsync, will fail without fix
  3. BbuReferenceDataSeeder - only uses raw SQL, but fix for consistency

Implementation Steps

Step 1: Fix CoreDataReferenceDataSeeder

File: engines/core-data/src/Acsis.Dynaplex.Engines.CoreData.Database/Seeding/CoreDataReferenceDataSeeder.cs

Change 1: Add ISystemDbContextUser interface to class declaration (line 12):

// FROM:
public class CoreDataReferenceDataSeeder(CoreDataDb db) : IReferenceDataSeeder

// TO:
public class CoreDataReferenceDataSeeder(CoreDataDb db) : IReferenceDataSeeder, ISystemDbContextUser

Change 2: Add SetSystemScope() call at the start of SeedAsync method (after line 15):

public async Task SeedAsync(string environment, ILogger logger, CancellationToken cancellationToken = default)
{
    db.SetSystemScope(SystemScopeReason.Seeding);  // Add this line

    await SeedIdentifierTypesAsync(logger, cancellationToken);
    // ... rest of method
}

Step 2: Fix PrismReferenceDataSeeder

File: engines/prism/src/Acsis.Dynaplex.Engines.Prism.Database/Seeding/PrismReferenceDataSeeder.cs

Change 1: Add ISystemDbContextUser interface to class declaration (line 10):

// FROM:
public class PrismReferenceDataSeeder(PrismDb db) : IReferenceDataSeeder

// TO:
public class PrismReferenceDataSeeder(PrismDb db) : IReferenceDataSeeder, ISystemDbContextUser

Change 2: Add SetSystemScope() call at the start of SeedAsync method (after line 15):

public async Task SeedAsync(string environment, ILogger logger, CancellationToken cancellationToken = default)
{
    db.SetSystemScope(SystemScopeReason.Seeding);  // Add this line

    logger.LogInformation("Starting reference data seeding for Prism");
    // ... rest of method
}

Step 3: Fix BbuReferenceDataSeeder (for consistency)

File: engines/bbu/src/Acsis.Dynaplex.Engines.Bbu.Database/Seeding/BbuReferenceDataSeeder.cs

Change 1: Add ISystemDbContextUser interface to class declaration (line 11):

// FROM:
public class BbuReferenceDataSeeder(BbuDb db) : IReferenceDataSeeder

// TO:
public class BbuReferenceDataSeeder(BbuDb db) : IReferenceDataSeeder, ISystemDbContextUser

Change 2: Add SetSystemScope() call at the start of SeedAsync method (after line 14):

public async Task SeedAsync(string environment, ILogger logger, CancellationToken cancellationToken = default)
{
    db.SetSystemScope(SystemScopeReason.Seeding);  // Add this line

    logger.LogInformation("Starting reference data seeding for BBU");
    // ... rest of method
}

Step 4: Rebuild and Redeploy

azd up

Step 5: Verify Seeding Success

Check db-manager logs for:

  • "UoM reference data seed completed successfully"
  • "Reference data seeding completed for Prism"
  • "Reference data seeding completed for BBU"
  • No tenant scope errors

Files to Modify

File Change
engines/core-data/src/Acsis.Dynaplex.Engines.CoreData.Database/Seeding/CoreDataReferenceDataSeeder.cs Add ISystemDbContextUser interface and SetSystemScope() call
engines/prism/src/Acsis.Dynaplex.Engines.Prism.Database/Seeding/PrismReferenceDataSeeder.cs Add ISystemDbContextUser interface and SetSystemScope() call
engines/bbu/src/Acsis.Dynaplex.Engines.Bbu.Database/Seeding/BbuReferenceDataSeeder.cs Add ISystemDbContextUser interface and SetSystemScope() call

Risk Assessment

Low Risk - This follows the exact same pattern as IdentityReferenceDataSeeder and SpatialReferenceDataSeeder which work correctly. The fix is minimal and well-understood.