Fix RunMigrations Propagation Issue (#6838)

* Introduce `MigrationOptions` for configurable EF Core migration execution

Added `MigrationOptions` to control migration execution on a per-DbContext basis. Updated `RunMigrationsStartupTask` to respect these options, and refactored configurations in `PersistenceFeatureBase`.

This fixes an issue where the `RunMigrations` setting is not properly propagated to dependency features.

Fixes #6912

* Propagate `DbContextOptionsBuilder`, `UseContextPooling`, and `RunMigrations` settings to dependency features in `WorkflowManagementPersistenceFeature`.

* Update src/modules/Elsa.EntityFrameworkCore.Common/RunMigrationsStartupTask.cs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Frans van Ek <frans@fransvanek.nl>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Sipke Schoorstra 2025-08-05 08:31:53 +02:00 committed by GitHub
parent aab80dd30b
commit 95346c98a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 30 additions and 6 deletions

View file

@ -0,0 +1,14 @@
namespace Elsa.EntityFrameworkCore;
public class MigrationOptions
{
/// <summary>
/// Gets or sets a collection that determines whether Entity Framework Core migrations
/// should be executed for specific DbContext types.
/// </summary>
/// <remarks>
/// The key is the DbContext type, and the value is a boolean indicating whether migrations
/// should be applied for that specific context (true to apply, false to skip).
/// </remarks>
public IDictionary<Type, bool> RunMigrations { get; set; } = new Dictionary<Type, bool>();
}

View file

@ -40,8 +40,7 @@ public abstract class PersistenceFeatureBase<TFeature, TDbContext>(IModule modul
public override void ConfigureHostedServices()
{
if (RunMigrations)
ConfigureMigrations();
ConfigureMigrations();
}
/// <inheritdoc />
@ -62,6 +61,11 @@ public abstract class PersistenceFeatureBase<TFeature, TDbContext>(IModule modul
Services.AddDbContextFactory<TDbContext>(setup, DbContextFactoryLifetime);
Services.Decorate<IDbContextFactory<TDbContext>, TenantAwareDbContextFactory<TDbContext>>();
Services.Configure<MigrationOptions>(options =>
{
options.RunMigrations[typeof(TDbContext)] = RunMigrations;
});
}
protected virtual void ConfigureMigrations()

View file

@ -2,6 +2,7 @@
using Elsa.Common.RecurringTasks;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
namespace Elsa.EntityFrameworkCore;
@ -11,11 +12,16 @@ namespace Elsa.EntityFrameworkCore;
[UsedImplicitly]
[SingleNodeTask]
[Order(-100)]
public class RunMigrationsStartupTask<TDbContext>(IDbContextFactory<TDbContext> dbContextFactory) : IStartupTask where TDbContext : DbContext
public class RunMigrationsStartupTask<TDbContext>(IDbContextFactory<TDbContext> dbContextFactory, IOptions<MigrationOptions> options) : IStartupTask where TDbContext : DbContext
{
/// <inheritdoc /
/// <inheritdoc />
public async Task ExecuteAsync(CancellationToken cancellationToken)
{
bool shouldRunMigrations = false;
options.Value.RunMigrations.TryGetValue(typeof(TDbContext), out shouldRunMigrations);
if (!shouldRunMigrations)
return;
var dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
await dbContext.Database.MigrateAsync(cancellationToken);
}

View file

@ -27,7 +27,7 @@ public class WorkflowManagementPersistenceFeature(IModule module) : PersistenceF
public override bool UseContextPooling
{
get => base.UseContextPooling;
get => base.UseContextPooling;
set
{
base.UseContextPooling = value;
@ -38,7 +38,7 @@ public class WorkflowManagementPersistenceFeature(IModule module) : PersistenceF
public override bool RunMigrations
{
get => base.RunMigrations;
get => base.RunMigrations;
set
{
base.RunMigrations = value;