Come abilitare le migrazioni EF per più contesti per separare i database?

Come abilitare le migrazioni di Entity Framework 5 (versione 5.0.0) per più contesti DB nello stesso progetto, in cui ogni contesto corrisponde al proprio database? Quando eseguo Enable-Migrations nella console PM (Visual Studio 2012), si verifica un errore a causa dell’esistenza di più contesti:

 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. 

Se Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContext non sono autorizzato a eseguire Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContext perché esiste già una migrazione: Le Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter. Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter.

    La seconda chiamata a Enable-Migrations non funziona perché il file Configuration.cs esiste già. Se rinomini quella class e il file, dovresti essere in grado di eseguire quel secondo Enable-Migrations, che creerà un altro Configuration.cs.

    Sarà quindi necessario specificare la configurazione che si desidera utilizzare durante l’aggiornamento dei database.

     Update-Database -ConfigurationTypeName MyRenamedConfiguration 

    Oltre a ciò che @ckal ha suggerito, è fondamentale assegnare a ciascun Configurationpace rinominato il proprio spazio dei nomi. In caso contrario, EF tenterà di applicare le migrazioni al contesto sbagliato.

    Ecco i passaggi specifici che funzionano bene per me.

    Se le migrazioni sono incasinate e vuoi creare una nuova “linea di base”:

    1. Elimina tutti i file .cs esistenti nella cartella Migrations
    2. In SSMS, eliminare la tabella di sistema __MigrationHistory.

    Creazione della migrazione iniziale:

    1. Nella console di Package Manager:

       Enable-Migrations -EnableAutomaticMigrations -ContextTypeName NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextA 
    2. In Esplora soluzioni: Rinomina Migrations.Configuration.cs in Migrations.ConfigurationA.cs. Questo dovrebbe rinominare automaticamente il costruttore se si utilizza Visual Studio. Assicurati che lo faccia. Modifica ConfigurationA.cs: cambia lo spazio dei nomi in NamespaceOfContext.Migrations.MigrationsA

    3.  Enable-Migrations -EnableAutomaticMigrations -ContextTypeName NamespaceOfContext.ContextB -ProjectName ProjectContextIsInIfNotMainOne -StartupProjectName NameOfMainProject -ConnectionStringName ContextB 
    4. In Esplora soluzioni: Rinomina Migrations.Configuration.cs in Migrations.ConfigurationB.cs. Di nuovo, assicurati che anche il costruttore sia rinominato in modo appropriato. Modifica ConfigurationB.cs: cambia lo spazio dei nomi in 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 

    Passi per creare script di migrazione in Package Manager Console:

    1. Esegui comando

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

      o –

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

      È corretto rieseguire questo comando fino a quando le modifiche non vengono applicate al DB.

    2. Eseguire gli script sul database locale desiderato oppure eseguire Update-Database senza -Script per applicare localmente:

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

      o –

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

    Ho appena incontrato lo stesso problema e ho utilizzato la seguente soluzione (tutto dalla console di Package Manager)

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

    Questo creerà 2 cartelle separate nella cartella Migrations. Ciascuno conterrà il file Configuration.cs generato. Sfortunatamente è ancora necessario rinominare i file Configuration.cs altrimenti si lamenteranno di averne due. Ho rinominato i miei file in ConfigA.cs e ConfigB.cs

    EDIT : (cortesia di Kevin McPheat) Ricordare quando si rinomina i file Configuration.cs, rinominare anche i nomi delle classi e i costruttori / EDIT

    Con questa struttura puoi semplicemente farlo

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

    Che creerà i file di codice per la migrazione all’interno della cartella accanto ai file di configurazione (questo è bello tenere insieme questi file)

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

    E, ultimo ma non meno importante, questi due comandi applicheranno le migrazioni corrette ai loro database corrseponding.

    EDIT 08 Feb 2016: Ho eseguito un piccolo test con EF7 versione 7.0.0-rc1-16348

    Non ho potuto far funzionare l’opzione -o | –outputDir. Continuava a fornire Microsoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument

    Tuttavia, sembra che la prima volta che viene aggiunta una migrazione venga aggiunta alla cartella Migrations e una successiva migrazione per un altro contesto viene automaticamente inserita in una sottodirectory di migrazioni.

    I nomi originali ContextA sembrano violare alcune convenzioni di denominazione, quindi ora utilizzo ContextAContext e ContextBContext . Usando questi nomi puoi usare i seguenti comandi: (nota che il mio dnx funziona ancora dalla console del gestore pacchetti e non mi piace aprire una finestra CMD separata per eseguire le migrazioni)

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

    Ciò creerà un’istantanea del modello e una migrazione iniziale nella cartella Migrations per ContextAContext . ContextB una cartella denominata ContextB contenente questi file per ContextBContext

    Ho aggiunto manualmente una cartella ContextA e spostato i file di migrazione da ContextAContext in quella cartella. Poi ho rinominato lo spazio dei nomi all’interno di quei file (file di istantanee, migrazione iniziale e nota che c’è un terzo file sotto il file di migrazione iniziale … designer.cs). Ho dovuto aggiungere .ContextA allo spazio dei nomi, e da lì il framework lo gestisce automaticamente di nuovo.

    L’utilizzo dei seguenti comandi creerebbe una nuova migrazione per ogni contesto

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

    e i file generati sono messi nelle cartelle corrette.

    Se hai già una “Configurazione” con molte migrazioni e vuoi mantenerla così com’è, puoi sempre creare una nuova class “Configurazione”, dargli un altro nome, come

     class MyNewContextConfiguration : DbMigrationsConfiguration { ... } 

    quindi basta emettere il comando

     Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName 

    e EF impalcerà la migrazione senza problemi. Infine aggiorna il tuo database, d’ora in poi, EF si lamenterà se non gli indichi quale configurazione si desidera aggiornare:

     Update-Database -ConfigurationTypeName MyNewContextConfiguration 

    Fatto.

    Non è necessario gestire Enable-Migrations poiché si lamenterà che “Configuration” esiste già e la ridenominazione della class di configurazione esistente porterà problemi alla cronologia delle migrazioni.

    È ansible scegliere come target database diversi o lo stesso, tutte le configurazioni condivideranno la tabella __MigrationHistory in modo corretto.