2016-10-04 6 views
3

Я разрабатываю проект установки с помощью Wix, и я устанавливаю базу данных, используя файл миграции .dll.Управление первыми миграциями элемента Entity Framework в проекте настройки

Я планировал использовать Migrate.exe для выполнения миграции из .dll, но есть требование, чтобы при запуске более новых версий установщика (с более новыми миграциями) я должен обновить базу данных. Я не мог найти способ перечислить все миграции с помощью Migrate.exe и запустить только те, которые не были запущены с установленной базой данных.

Знаете ли вы способ выполнить это требование с помощью Migrate.exe или любого другого инструмента или фреймворка, который позволит мне отслеживать миграции и запускать только те, которые не выполняются для базы данных?

Я должен быть в состоянии реализовать предлагаемые функции в проекте установщика, чтобы он работал.

Спасибо.

С наилучшими пожеланиями, Евгений Dyulgerov

+0

Вы имеете в виду Entity Framework Code Первые миграции? Если это так, то имеет смысл добавить это в заголовок или сам вопрос –

+0

Да - я добавил его. Благодарю. –

ответ

0

Вам не нужно запускать сценарии миграции во время установки - установщику потребуется слишком высокие привилегии, чтобы сделать это, и вы можете иметь проблемы с установкой политик пакета прикладной системными администраторами от активного Справочник.

Обновление Db также является логикой приложения, и я считаю, что оно принадлежит к приложению, а не к установщику.

Конечно, вы можете сделать это в wix with custom actions. Но вам придется загружать все сборки, необходимые для миграции, - выполнять команды SQL по крайней мере.

Я рекомендую вам запустить миграцию в своем приложении.

Вот отрезанный, который выполняет эту работу. Сначала давайте скачим какой-то контекст:

  1. У вас есть N континуальных миграций, которые вы создали во время циклов разработки проекта.
  2. Вы можете использовать инструментарий EF из консоли диспетчера пакетов в Visual Studio или непосредственно (файл .exe, который вы можете найти в пакете nuget), чтобы создать частичные (обновления) миграции. Затем вы скомпилируете их в сборке миграции, чтобы они были перенесены с вашим приложением в клиента с помощью установщика. Пример:.

    Add-Migration -Name SomeDbChangeDescription -StartUpProjectName TheCoreProjectWithConfig -ProjectName TheProjectWithMigrations -ConfigurationTypeName "Fully.Qualified.Type.Name.Of.MigrationConfiguration" -ConnectionString «Источник данных = \ SQLINSTANCE; Database = мой дБ; Trusted_Connection = False; ID пользователя = ххх; Password = ххх»-ConnectionProviderName„System.Data.SqlClient“

Помните, что с помощью этого сценария можно создавать миграционную скрипт из одной БД, но вы можете впоследствии применить его на нескольких базы данных - когда у вас есть db-per-tenant. Вам не нужно генерировать сценарий миграции для каждой базы данных, если они основаны на одной и той же модели, потому что в генерации миграции в процессе генерации не содержится никакой конкретной информации о БД.

  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.