2016-10-04 3 views
3

Je développe un projet d'installation avec Wix et j'installe une base de données en utilisant un fichier de migration .dll. Je prévoyais d'utiliser Migrate.exe pour exécuter les migrations à partir du fichier .dll, mais il est nécessaire que si de nouvelles versions du programme d'installation sont exécutées (avec des migrations plus récentes), je dois mettre à jour la base de données. Je n'ai pas pu trouver un moyen de lister toutes les migrations avec Migrate.exe et d'exécuter uniquement celles qui n'ont pas été exécutées sur la base de données installée. Connaissez-vous un moyen de remplir cette condition avec Migrate.exe, ou tout autre outil ou cadre, qui me permettrait de suivre les migrations et d'exécuter uniquement celles qui ne sont pas exécutées pour une base de données?Gérer les premières migrations du code Entity Framework dans un projet d'installation

Je devrais pouvoir implémenter la fonctionnalité suggérée dans le projet d'installation pour que cela fonctionne.

Merci.

Meilleures salutations, Evgeni Dyulgerov

+0

Faites-vous référence à Entity Framework Code First migrations? Si oui, alors il serait logique d'ajouter cela dans le titre ou la question elle-même –

+0

Oui - je l'ai ajouté. Merci. –

Répondre

0

Vous n'avez pas besoin d'exécuter des scripts de migration lors de l'installation - votre installateur aura besoin de privilèges trop élevés pour le faire et vous pouvez avoir des problèmes avec l'installation des stratégies de package appliquées par les administrateurs système à partir d'Active Annuaire.

La mise à niveau de la base de données est aussi une logique d'application et je crois qu'elle appartient à l'application - pas à l'installateur. Bien sûr, vous pouvez le faire en wix with custom actions. Mais vous devrez charger tous les assemblages requis pour la migration - exécutez au moins les commandes SQL.

Je vous recommande d'exécuter les migrations au démarrage de votre application.

Voici un piqué qui fait le travail. Tout d'abord, changeons de contexte:

  1. Vous avez effectué N migrations consécutives que vous avez créées pendant les cycles de développement du projet.
  2. Vous pouvez utiliser les outils EF de la console du gestionnaire de packages dans Visual Studio ou directement (le fichier .exe que vous pouvez trouver dans le package nuget) pour créer vos migrations partielles (mise à jour). Vous les compilerez ensuite dans l'assemblage de migrations afin qu'elles soient transportées avec votre application vers le client avec l'installateur. Un exemple:.

    Add-Migration -Nom SomeDbChangeDescription -StartUpProjectName TheCoreProjectWithConfig -ProjectName TheProjectWithMigrations -ConfigurationTypeName "Fully.Qualified.Type.Name.Of.MigrationConfiguration" -ConnectionString « Data Source = \ SQLinstance; Base de données = my-db; Trusted_Connection = False ID utilisateur = xxx; Mot de passe = xxx » -ConnectionProviderName "System.Data.SqlClient"

Rappelez-vous que ce script vous générez un script de migration d'un db, mais vous pouvez ensuite l'appliquer sur plusieurs bases de données - lorsque vous avez db-per-locataire. Vous n'avez pas besoin de générer un script de migration pour chaque base de données si elles proviennent du même modèle car aucune information spécifique à la base de données n'est codée en dur dans le script de migrations au cours de la génération.

  1. Vous compilez votre assembly de migrations et assurez-vous qu'il figure dans le programme d'installation et qu'il est chargé au démarrage de l'application.

Maintenant vous pouvez utiliser (modifier comme vous voulez) le code suivant. dbMigrator.Update() appliquera tous les scripts de migrations qui doivent être appliqués - si vous avez 10 migrations dans l'assembly avec 2 migrations non appliquées, il comparera le modèle de la base de données et toutes les migrations et appliquera uniquement les 2 dernières migrations. Si vous appelez la méthode dbMigrator.Update() avec un nom de base de données qui n'existe pas, elle créera une nouvelle base de données en appliquant le script initial et toutes les autres mises à jour partielles.

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

MISE À JOUR Vous pouvez appliquer une autre approche -

  1. Utilisez le script AddMigration mentionné ci-dessus au cours du développement et ajoutez la directive -Script pour obtenir le script de migration SQL au lieu de script de migration C#.
  2. Utilisez WIX Sql Extension pour l'exécuter lors de l'installation. The official Sql Extension for Wix Documentation.