使用 FluentMigrator 获取挂起迁移的内容

Get content of pending migrations using FluentMigrator

我有使用 FluentMigrator 迁移的控制台应用程序,但现在我需要在实际迁移过程之前实施用户确认。我进入了 repo 资源,了解了版本加载器以及如何使用 IServiceProvider 获取未应用的迁移列表。但是还找不到一种方法来打印 SQL 将在 MigrateUp() 中使用的迁移脚本。我也在使用 SQL 服务器包。谁能指点方向?

private static void UpdateDatabase(IServiceProvider serviceProvider)
{
    var runner = serviceProvider.GetRequiredService<IMigrationRunner>();
    var versionLoader = serviceProvider.GetRequiredService<IVersionLoader>();
    var migrationContext = serviceProvider.GetRequiredService<IMigrationContext>();

    var migrations = runner.MigrationLoader.LoadMigrations()
        .Where(migration => !versionLoader.VersionInfo.HasAppliedMigration(migration.Key))
        .ToList();

    // print migrations up expressions
    foreach (var migration in migrations)
    {
        Console.WriteLine($"Pending migration: {migration.Value.GetName()}");
        Console.WriteLine("SQL:");

        migration.Value.Migration.GetUpExpressions(migrationContext);

        foreach (var expression in migrationContext.Expressions)
        {
            Console.WriteLine(expression); // this just outputs "CreateTable Test" in my case
        }
    }

    bool userAccepted = true; // TODO: get confirmation from user

    if (!userAccepted)
        return;

    // Execute the migrations
    runner.MigrateUp();
}

IMigrationGenerator可以用IServiceProvider解决。但是,不幸的是,没有支持 IMigrationExpression 参数的方法(见下文),所以我不得不为每种类型编写 if-else 语句墙或使用反射。我使用了第二个选项。也许有更好的方法?

var migrationGenerator = serviceProvider.GetRequiredService<IMigrationGenerator>();

// print migrations up expressions
foreach (var migration in migrations)
{
    Console.WriteLine($"Pending migration: {migration.Value.GetName()}");
    Console.WriteLine("SQL:");

    migration.Value.Migration.GetUpExpressions(migrationContext);

    foreach (var expression in migrationContext.Expressions)
    {
        if (expression is ExecuteSqlScriptExpression executeSqlScriptExpression)
        {
            Console.WriteLine(executeSqlScriptExpression.SqlScript);
        }
        else if (expression is ExecuteSqlStatementExpression executeSqlStatementExpression)
        {
            Console.WriteLine(executeSqlStatementExpression.SqlStatement);
        }
        else
        {
            var processMethod = migrationGenerator.GetType().GetMethod("Generate", new[] { expression.GetType() });
            var sql = (string)processMethod.Invoke(migrationGenerator, new[] { expression });

            Console.WriteLine(sql);
        }
    }
}