128 votes

Comment activer les migrations EF pour plusieurs contextes vers des bases de données distinctes ?

Comment activer les migrations Entity Framework 5 (version 5.0.0) pour plusieurs contextes DB dans le même projet, où chaque contexte correspond à sa propre base de données ? Lorsque je lance Enable-Migrations dans la console PM (Visual Studio 2012), il y a une erreur car il y a plusieurs contextes :

PM> Enable-Migrations
More than one context type was found in the assembly 'DatabaseService'.
To enable migrations for DatabaseService.Models.Product1DbContext, use Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext.
To enable migrations for DatabaseService.Models.Product2DbContext, use Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext.

Si je cours Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext Je n'ai pas le droit de courir Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext parce qu'une migration existe déjà : Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter.

4 votes

131voto

ckal Points 1551

Le deuxième appel à Enable-Migrations échoue parce que le fichier Configuration.cs existe déjà. Si vous renommez cette classe et ce fichier, vous devriez pouvoir exécuter ce deuxième appel à Enable-Migrations, qui créera un autre Configuration.cs.

Vous devrez ensuite spécifier la configuration que vous souhaitez utiliser lors de la mise à jour des bases de données.

Update-Database -ConfigurationTypeName MyRenamedConfiguration

1 votes

Qu'est-ce que "MyRenamedConfiguration" ?

1 votes

"MyRenamedConfiguration" n'est qu'un texte de remplacement à titre d'exemple. Vous auriez pu renommer votre Configuration.cs original en n'importe quel nom (par exemple FooBar, puis exécuter Update-Database -ConfigurationTypeName FooBar).

4 votes

Abréger la forme : Update-Database -conf MyRenamedConfiguration

105voto

Eric J. Points 73338

En plus de ce que @ckal a suggéré, c'est critique pour donner à chaque Configuration.cs renommé son propre espace de noms. Si vous ne le faites pas, EF tentera d'appliquer les migrations au mauvais contexte.

Voici les étapes spécifiques qui fonctionnent bien pour moi.

Si les migrations sont perturbées et que vous souhaitez créer une nouvelle "ligne de base" :

  1. Supprimer tous les fichiers .cs existants dans le dossier Migrations
  2. Dans SSMS, supprimez la table système __MigrationHistory.

Création de la migration initiale :

  1. Dans la console du gestionnaire de paquets :

    Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextA
  2. Dans l'explorateur de solutions : Renommer Migrations.Configuration.cs en Migrations.ConfigurationA.cs. Cela devrait automatiquement renommer le constructeur si vous utilisez Visual Studio. Assurez-vous que c'est bien le cas. Modifier ConfigurationA.cs : Modifier l'espace de noms en NamespaceOfContext.Migrations.MigrationsA.

  3. Enable-Migrations -EnableAutomaticMigrations -ContextTypeName NamespaceOfContext.ContextB -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextB

  4. Dans l'explorateur de solutions : Renommer Migrations.Configuration.cs en Migrations.ConfigurationB.cs. Veillez à ce que le constructeur soit également renommé de manière appropriée. Modifier ConfigurationB.cs : Modifier l'espace de noms en NamespaceOfContext.Migrations.MigrationsB

  5. add-migration InitialBSchema -IgnoreChanges -ConfigurationTypeName ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextB

  6. Update-Database -ConfigurationTypeName ConfigurationB -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextB

  7. add-migration InitialSurveySchema -IgnoreChanges -ConfigurationTypeName ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextA

  8. Update-Database -ConfigurationTypeName ConfigurationA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextA

Étapes à suivre pour créer des scripts de migration dans la console du gestionnaire de paquets :

  1. Exécuter la commande

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

    ou -

    Add-Migration MYMIGRATION -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB

    Il est possible de réexécuter cette commande jusqu'à ce que les changements soient appliqués à la base de données.

  2. Exécutez les scripts contre la base de données locale souhaitée, ou exécutez Update-Database sans -scripts pour l'appliquer localement :

    Update-Database -ConfigurationTypeName ConfigurationA -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextA

    ou -

    Update-Database -ConfigurationTypeName ConfigurationB -ProjectName
    ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject
    -ConnectionStringName ContextB

0 votes

4 changement : Modifier ConfigurationA.cs -> Modifier ConfigurationB.cs

1 votes

@Biran : Merci de l'avoir remarqué. J'ai édité la réponse. Notez que vous pouvez également modifier les réponses vous-même. Comme vous n'avez pas encore 2000 points de réputation, vos réponses sont placées dans une file d'attente de révision, mais cette file d'attente est généralement traitée rapidement, de sorte que votre modification aurait probablement été approuvée en quelques minutes.

5 votes

MERCI ! C'est ce qui me manquait (les espaces de noms).

85voto

bart s Points 2811

Je viens de rencontrer le même problème et j'ai utilisé la solution suivante (à partir de la console du gestionnaire de paquets)

PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextA" -ContextTypeName MyProject.Models.ContextA
PM> Enable-Migrations -MigrationsDirectory "Migrations\ContextB" -ContextTypeName MyProject.Models.ContextB

Cela créera deux dossiers distincts dans le dossier Migrations. Chacun d'eux contiendra les fichiers Configuration.cs dossier. Malheureusement, vous devez encore renommer ces Configuration.cs Sinon, on se plaindra d'en avoir deux. J'ai renommé mes fichiers en ConfigA.cs y ConfigB.cs

EDIT (avec l'aimable autorisation de Kevin McPheat) N'oubliez pas que lorsque vous renommez les fichiers Configuration.cs, vous devez également renommer les noms des classes et des constructeurs. /EDIT

Avec cette structure, vous pouvez simplement faire

PM> Add-Migration -ConfigurationTypeName ConfigA
PM> Add-Migration -ConfigurationTypeName ConfigB

Ce qui créera les fichiers de code pour la migration dans le dossier à côté des fichiers de configuration (ce qui permet de garder ces fichiers ensemble).

PM> Update-Database -ConfigurationTypeName ConfigA
PM> Update-Database -ConfigurationTypeName ConfigB

Enfin, ces deux commandes appliqueront les migrations correctes aux bases de données correspondantes.

EDIT 08 Feb, 2016 : J'ai fait quelques tests avec la version 7.0.0-rc1-16348 de EF7.

Je n'ai pas réussi à faire fonctionner l'option -o|--outputDir. Elle continuait à donner Microsoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument

Cependant, il semble que la première fois qu'une migration est ajoutée, elle est placée dans le dossier Migrations, et qu'une migration ultérieure pour un autre contexte est automatiquement placée dans un sous-dossier des migrations.

Les noms originaux ContextA semble violer certaines conventions de dénomination, j'utilise donc maintenant ContextAContext y ContextBContext . En utilisant ces noms, vous pouvez utiliser les commandes suivantes : (notez que mon dnx fonctionne toujours à partir de la console du gestionnaire de paquets et que je n'aime pas ouvrir une fenêtre CMD séparée pour effectuer des migrations)

PM> dnx ef migrations add Initial -c "ContextAContext"
PM> dnx ef migrations add Initial -c "ContextBContext"

Cela créera un instantané du modèle et une migration initiale dans le fichier Migrations dossier pour ContextAContext . Il créera un dossier nommé ContextB contenant ces fichiers pour ContextBContext

J'ai ajouté manuellement un ContextA et déplacé les fichiers de migration de ContextAContext dans ce dossier. J'ai ensuite renommé l'espace de noms à l'intérieur de ces fichiers (fichier d'instantané, migration initiale et notez qu'il y a un troisième fichier sous le fichier de migration initiale ... designer.cs). J'ai dû ajouter .ContextA à l'espace de noms, et à partir de là, le cadre de travail le gère à nouveau automatiquement.

Les commandes suivantes permettent de créer une nouvelle migration pour chaque contexte

PM>  dnx ef migrations add Update1 -c "ContextAContext"
PM>  dnx ef migrations add Update1 -c "ContextBContext"

et les fichiers générés sont placés dans les bons dossiers.

7voto

GLM Points 868

Si vous avez déjà une "Configuration" avec de nombreuses migrations et que vous souhaitez la conserver telle quelle, vous pouvez toujours créer une nouvelle classe "Configuration" et lui donner un autre nom, comme par exemple

class MyNewContextConfiguration : DbMigrationsConfiguration<MyNewDbContext>
{
   ...
}

Il suffit alors de lancer la commande

Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName

et l'EF assureront la migration sans problème. Enfin, mettez à jour votre base de données, à partir de maintenant, EF se plaindra si vous ne lui dites pas quelle configuration vous voulez mettre à jour :

Update-Database -ConfigurationTypeName MyNewContextConfiguration 

Fait.

Vous n'avez pas besoin d'activer les migrations, car le système se plaindra que "Configuration" existe déjà, et le fait de renommer votre classe de configuration existante entraînera des problèmes dans l'historique des migrations.

Vous pouvez cibler différentes bases de données, ou la même, toutes les configurations partageront la table __MigrationHistory.

5voto

AHAMED AAQIB Points 19

Si plusieurs bases de données existent, utilisez les codes suivants dans PowerShell

Add-Migration Starter -context EnrollmentAppContext 
  • Starter" est le nom de la migration

  • EnrollmentAppContext' est le nom de mon application Contexte

Vous pouvez ouvrir PowerShell dans VS en faisant : Tools->NuGet Package Manager->Package Manager Console

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X