您不需要在安装过程中运行迁移脚本 - 您的安装程序将需要太高的权限才能执行此操作,并且您可能会遇到系统管理员从 Active Directory 应用的安装包策略的问题。
Db 升级也是应用程序逻辑,我相信它属于应用程序 - 而不是安装程序。
当然可以在wix with custom actions 中进行。但是您必须加载迁移所需的所有程序集 - 至少运行 SQL 命令。
我建议您在应用启动时运行迁移。
这是一个可以完成这项工作的片段。首先让我们了解一些上下文:
- 您在项目开发周期中创建了 N 个后续迁移。
-
您可以使用 Visual Studio 中包管理器控制台中的 EF 工具或直接使用(您可以在 nuget 包中找到的 .exe)来创建部分(更新)迁移。之后,您将在迁移程序集中编译它们,以便通过安装程序将它们与您的应用程序一起带到客户端。一个例子:
Add-Migration -Name SomeDbChangeDescription -StartUpProjectName TheCoreProjectWithConfig -ProjectName TheProjectWithMigrations -ConfigurationTypeName "Fully.Qualified.Type.Name.Of.MigrationConfiguration" -ConnectionString "Data Source=.\SQLINSTANCE;Database=my-db;Trusted_Connection=False;用户 ID=xxx;密码=xxx" -ConnectionProviderName "System.Data.SqlClient"
请记住,使用此脚本,您可以从一个 db 生成迁移脚本,但您可以稍后将其应用于多个数据库 - 当您拥有 db-per-tenant 时。如果每个数据库源自同一模型,则无需为每个数据库生成迁移脚本,因为在生成过程中迁移脚本中没有硬编码数据库特定信息。
- 您编译迁移程序集并确保它在安装程序中并且在应用启动时加载。
现在您可以使用(随意修改)以下代码。 dbMigrator.Update() 将应用所有需要应用的迁移脚本 - 如果您在程序集中有 10 个迁移,其中 2 个未应用迁移,它将比较数据库的模型和所有迁移,并且仅应用最后 2 个。如果您使用不存在的数据库名称调用 dbMigrator.Update() 方法,它将创建应用初始脚本和所有其他部分更新的新数据库。
public class DbInitializer : IDbInitializer
{
private readonly IConnectionStringProvider _connectionStringProvider;
public DbInitializer(IConnectionStringProvider connectionStringProvider)
{
_connectionStringProvider = connectionStringProvider;
}
public void CreateOrUpdateDb(string dbName)
{
try
{
string connectionString = _connectionStringProvider.GetConnectionString(dbName);
DbMigrationsConfiguration cfg = CreateMigrationsConfig(connectionString);
cfg.CommandTimeout = 900;
cfg.AutomaticMigrationsEnabled = false;
cfg.AutomaticMigrationDataLossAllowed = false;
DbMigrator dbMigrator = new DbMigrator(cfg);
var pendingMigrations = dbMigrator.GetPendingMigrations().ToArray();
if(pendingMigrations.Length > 0)
{
foreach(var pendingMigration in pendingMigrations)
{
InitializerEventSource.Log.UpgradingDb(dbName, pendingMigration);
}
dbMigrator.Update();
DbInitializerEventSource.Log.UpgradedDb(dbName);
}
}
catch(MigrationsException exception)
{
// exception handling
}
catch(Exception exception)
{
// exception handling
}
}
private DbMigrationsConfiguration<InitDbContext> CreateMigrationsConfig(string connectionString)
{
DbMigrationsConfiguration<InitDbContext> cfg = new DbMigrationsConfiguration<InitDbContext>
{
AutomaticMigrationsEnabled = false,
AutomaticMigrationDataLossAllowed = false,
MigrationsAssembly = Assembly.Load("TheAssemblyContainingTheMigrations"),
MigrationsNamespace = "TheNamespaceWhereTheMigrationsAre",
ContextKey = "HardCodedContexKey",
TargetDatabase = new DbConnectionInfo(connectionString, _connectionStringProvider.ProviderInvariantName)
};
return cfg;
}
}
更新
您可以应用另一种方法 -
- 在开发过程中使用上面提到的AddMigration脚本并添加-Script指令来获取SQL迁移脚本而不是C#迁移脚本。
- 在安装过程中使用WIX Sql Extension 执行它。 The official Sql Extension for Wix Documentation.