使用 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);
}
}
}
我有使用 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);
}
}
}