【问题标题】:Get content of pending migrations using FluentMigrator使用 FluentMigrator 获取挂起迁移的内容
【发布时间】:2023-04-10 01:26:02
【问题描述】:

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

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();
}

【问题讨论】:

标签: c# .net-core-3.1 fluent-migrator


【解决方案1】:

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);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 2015-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-31
    • 2014-05-02
    相关资源
    最近更新 更多