2016-10-04 120 views
3

我正在用Wix开发安装项目,并且我正在使用迁移.dll文件安装数据库。在设置项目中管理实体框架代码第一次迁移

我打算使用Migrate.exe来执行.dll的迁移,但需要运行更新版本的安装程序(使用较新的迁移),我必须更新数据库。我找不到用Migrate.exe列出所有迁移的方法,并只运行那些尚未针对已安装的数据库运行的迁移。

你知道的方式来实现与Migrate.exe这一要求,或其他任何工具或框架,这将让我跟踪迁移和只运行那些不为数据库执行的?

我应该能够实现,以便为它工作在安装项目建议的功能。

谢谢。

最好的问候, 叶夫根Dyulgerov

+0

您是指Entity Framework Code First迁移?如果是这样,那么在标题或问题本身中添加 –

+0

是的 - 我添加了它。谢谢。 –

回答

0

你不需要在安装过程中运行迁移脚本 - 您的安装需要太高的权限这样做,你可能有安装由系统管理员从主动应用包策略问题目录。

Db的升级应用程序逻辑也是一样,我相信它是属于应用程序 - 而不是安装程序。

当然你也可以在wix with custom actions做到这一点。但是你将不得不加载迁移所需的所有程序集 - 至少需要运行SQL命令。

我建议您在应用程序启动时运行迁移。

这是一个剪裁,完成这项工作。首先让我们来回顾一下上下文:

  1. 您在项目开发周期中创建了N个连续的迁移。
  2. 您可以使用EF工具从包管理器控制台在Visual Studio或直接(你可以在NuGet包找到.exe文件)来创建局部(更新)迁移。之后您将在迁移程序集中编译它们,以便将它们与您的应用程序一起带到安装程序的客户端。举个例子:。

    添加迁移-Name SomeDbChangeDescription -StartUpProjectName TheCoreProjectWithConfig -ProjectName TheProjectWithMigrations -ConfigurationTypeName “Fully.Qualified.Type.Name.Of.MigrationConfiguration” -ConnectionString“数据源= \ SQLINSTANCE;数据库=我-DB; Trusted_Connection = FALSE;用户ID = XXX;密码= XXX” -ConnectionProviderName‘System.Data.SqlClient的’

记住,使用该脚本您1分贝产生迁移脚本,但以后可以把它在多个数据库 - 当你有db-per-tenant时。如果源自同一模型,则不需要为每个数据库生成迁移脚本,因为在生成过程中在迁移脚本中没有硬编码特定于DB的信息。

  1. 您可以编译您的迁移程序集并确保它在安装程序中,并且它在应用程序启动时加载。

现在您可以使用(随意修改)以下代码。 dbMigrator.Update()将应用所有需要应用的迁移脚本 - 如果您在程序集中有10次迁移并且有2次未应用迁移,它将比较db的模型和所有迁移,并将仅应用最后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; 
     }  
} 

UPDATE 你可以申请另一种方法 - 在开发过程中

  1. 使用上述AddMigration脚本,并添加-Script指令获取SQL迁移脚本,而不是C#迁移脚本。
  2. 使用WIX Sql Extension在安装过程中执行它。 The official Sql Extension for Wix Documentation.