Wie aktiviere ich EF-Migrationen für mehrere Kontexte, um Datenbanken zu trennen?


122

Wie aktiviere ich Entity Framework 5-Migrationen (Version 5.0.0) für mehrere DB-Kontexte im selben Projekt, wobei jeder Kontext einer eigenen Datenbank entspricht? Wenn ich Enable-Migrationsin der PM-Konsole (Visual Studio 2012) ausgeführt werde, tritt ein Fehler auf, da mehrere Kontexte vorhanden sind:

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.

Wenn ich ausgeführt Enable-Migrations -ContextTypeName DatabaseService.Models.Product1DbContextwerde, darf ich nicht ausgeführt werden, Enable-Migrations -ContextTypeName DatabaseService.Models.Product2DbContextda bereits eine Migration vorhanden ist:Migrations have already been enabled in project 'DatabaseService'. To overwrite the existing migrations configuration, use the -Force parameter.


Antworten:


126

Der zweite Aufruf von Enable-Migrations schlägt fehl, da die Datei Configuration.cs bereits vorhanden ist. Wenn Sie diese Klasse und Datei umbenennen, sollten Sie in der Lage sein, diese 2. Aktivierungsmigrationen auszuführen, wodurch eine weitere Configuration.cs erstellt wird.

Anschließend müssen Sie angeben, welche Konfiguration Sie beim Aktualisieren der Datenbanken verwenden möchten.

Update-Database -ConfigurationTypeName MyRenamedConfiguration

1
Was ist "MyRenamedConfiguration"?
Robert Noack

1
"MyRenamedConfiguration" ist nur ein Platzhaltertext als Beispiel. Sie hätten Ihre ursprüngliche Configuration.cs in etwas umbenennen können (z. B. FooBar, dann Update-Database -ConfigurationTypeName FooBar ausführen).
ckal

3
Formular kürzen: Update-Database -conf MyRenamedConfiguration
Peter Kerr

100

Zusätzlich zu dem, was @ckal vorgeschlagen hat, ist es kritisch jeder umbenannt Configuration.cs seinen eigenen Namensraum zu geben. Wenn Sie dies nicht tun, versucht EF, Migrationen auf den falschen Kontext anzuwenden.

Hier sind die spezifischen Schritte, die für mich gut funktionieren.

Wenn Migrationen durcheinander sind und Sie eine neue "Baseline" erstellen möchten:

  1. Löschen Sie alle vorhandenen CS-Dateien im Migrationsordner
  2. Löschen Sie in SSMS die Systemtabelle __MigrationHistory.

Erstellen der ersten Migration:

  1. In der Package Manager-Konsole:

    Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextA -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextA
  2. Im Projektmappen-Explorer: Benennen Sie Migrations.Configuration.cs in Migrations.ConfigurationA.cs um. Dies sollte den Konstruktor automatisch umbenennen, wenn Sie Visual Studio verwenden. Stellen Sie sicher, dass dies der Fall ist. ConfigurationA.cs bearbeiten: Ändern Sie den Namespace in NamespaceOfContext.Migrations.MigrationsA

  3. Enable-Migrations -EnableAutomaticMigrations -ContextTypeName
    NamespaceOfContext.ContextB -ProjectName ProjectContextIsInIfNotMainOne
    -StartupProjectName NameOfMainProject  -ConnectionStringName ContextB
  4. Im Projektmappen-Explorer: Benennen Sie Migrations.Configuration.cs in Migrations.ConfigurationB.cs um. Stellen Sie erneut sicher, dass der Konstruktor auch entsprechend umbenannt wird. ConfigurationB.cs bearbeiten: Ändern Sie den Namespace 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

Schritte zum Erstellen von Migrationsskripten in der Package Manager-Konsole:

  1. Führen Sie den Befehl aus

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

    oder -

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

    Es ist in Ordnung, diesen Befehl erneut auszuführen, bis Änderungen auf die Datenbank angewendet werden.

  2. Führen Sie die Skripte entweder für die gewünschte lokale Datenbank aus oder führen Sie Update-Database without -Script aus, um sie lokal anzuwenden:

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

    oder -

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

# 4 Änderung: Edit ConfigurationA.cs -> Edit ConfigurationB.cs
Brian Rizo

1
@Biran: Danke, dass du das bemerkt hast. Ich habe die Antwort bearbeitet. Beachten Sie, dass Sie die Antworten auch selbst bearbeiten können. Da Sie noch keinen Ruf von 2000 haben, werden Ihre Antworten in eine Überprüfungswarteschlange gestellt, aber diese Warteschlange wird normalerweise schnell bearbeitet, sodass Ihre Bearbeitung wahrscheinlich innerhalb weniger Minuten genehmigt worden wäre.
Eric J.

5
DANKE! Das hat mir gefehlt (die Namespaces).
William M. Rawls

Dies kann hilfreich sein, da mir zunächst nicht klar war, wie die Umbenennung in den Schritten 2 und 4 erfolgen soll : Wenn Sie die Datei Configuration.cs in ConfigurationA.cs oder ConfigurationB.cs umbenennen, sollte die Umbenennung auch zu class und führen Der Konstruktor wird ebenfalls in ConfigurationA oder ConfigurationB umbenannt. Wenn Sie die Klasse nicht umbenennen, wird eine Fehlermeldung angezeigt, wenn Sie den Befehl add-migration ausführen - "Der Migrationskonfigurationstyp 'ConfigurationA' wurde in der Assembly '...' nicht gefunden" - und ja, der Wortlaut war genauso schlecht wie das in den Fehlermeldungen, die ich in VS2013 - LOL
Greg Barth

3
das hat mir geholfen! Vollständige Anleitung mit allen Optionen und Bestellungen. hat mir Stunden gespart
elcool

81

Ich bin gerade auf dasselbe Problem gestoßen und habe die folgende Lösung verwendet (alle von Package Manager Console).

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

Dadurch werden zwei separate Ordner im Migrationsordner erstellt. Jedes enthält die generierte Configuration.csDatei. Leider müssen Sie diese Configuration.csDateien noch umbenennen, da sonst Beschwerden über zwei davon auftreten. Ich habe meine Dateien in ConfigA.csund umbenanntConfigB.cs

BEARBEITEN : (mit freundlicher Genehmigung von Kevin McPheat) Denken Sie beim Umbenennen der Configuration.cs-Dateien auch daran, die Klassennamen und Konstruktoren / EDIT umzubenennen

Mit dieser Struktur können Sie einfach tun

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

Dadurch werden die Codedateien für die Migration im Ordner neben den Konfigurationsdateien erstellt (dies ist hilfreich, um diese Dateien zusammenzuhalten).

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

Und last but not least wenden diese beiden Befehle die richtigen Migrationen auf die entsprechenden Datenbanken an.

EDIT 08 Feb, 2016: Ich habe ein wenig mit EF7 Version 7.0.0-rc1-16348 getestet

Ich konnte die Option -o | --outputDir nicht zum Laufen bringen. Es gab weiterMicrosoft.Dnx.Runtime.Common.Commandline.CommandParsingException: Unrecognized command or argument

Es sieht jedoch so aus, als würde eine Migration beim ersten Hinzufügen zum Ordner "Migrationen" hinzugefügt, und eine nachfolgende Migration für einen anderen Kontext wird automatisch in einen Unterordner von Migrationen eingefügt.

Die ursprünglichen Namen ContextAscheinen gegen einige Namenskonventionen zu verstoßen, daher verwende ich jetzt ContextAContextundContextBContext . Unter Verwendung dieser Namen können Sie die folgenden Befehle verwenden: (Beachten Sie, dass mein dnx immer noch über die Paketmanagerkonsole funktioniert und ich kein separates CMD-Fenster öffnen möchte, um Migrationen durchzuführen.)

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

Dadurch werden ein Modellschnappschuss und eine erste Migration im MigrationsOrdner für erstellt ContextAContext. Es wird ein Ordner mit dem Namen erstelltContextB , der diese Dateien für enthältContextBContext

Ich habe manuell einen ContextAOrdner hinzugefügt und die Migrationsdateien aus ContextAContextdiesem Ordner verschoben . Dann habe ich den Namespace in diesen Dateien umbenannt (Snapshot-Datei, anfängliche Migration und beachten Sie, dass sich unter der anfänglichen Migrationsdatei eine dritte Datei befindet ... designer.cs). Ich musste .ContextAdem Namespace etwas hinzufügen , und von dort aus behandelt das Framework es automatisch wieder.

Mit den folgenden Befehlen wird für jeden Kontext eine neue Migration erstellt

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

und die generierten Dateien werden in den richtigen Ordnern abgelegt.


5
Die beste Lösung, einfach und wir haben einen übersichtlichen Ordner.
Malick

2
Dies war die Antwort, die ich brauchte. Der über -MigrationsDirectory hinzugefügte Namespace war die Antwort! Danke dir.
Crob

1
Schöne und saubere Lösung. Vielen Dank.
Stefan Cebulak

4
1,5 Jahre später bin ich froh, dass ich mit meinem eigenen Beitrag ein neues Projekt einrichten kann.
Bart s

1
Beachten Sie, add-migrationdass Sie beim Ausführen dazu aufgefordert werden Name. Dies warf mich leicht ab, da ich bereits zur Verfügung stellte ConfigurationTypeNameund wurde leicht genervt, als es gerade sagte Name:. Aber natürlich ist der gewünschte Name die "vom Menschen lesbare" Beschreibung der Änderung - z. AddedProductsoder IncreaseLengthOfNameFields. Im Ordner "Migrationen" wird dies als Teil des Klassennamens angezeigt, sodass Sie leicht erkennen können, was was ist. In der Tat Nameist das wie ein Check-in-Kommentar.
Simon_Weaver

7

Falls Sie bereits eine "Konfiguration" mit vielen Migrationen haben und diese unverändert lassen möchten, können Sie jederzeit eine neue "Konfigurations" -Klasse erstellen und ihr einen anderen Namen geben, z

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

dann geben Sie einfach den Befehl ein

Add-Migration -ConfigurationTypeName MyNewContextConfiguration InitialMigrationName

und EF wird die Migration ohne Probleme durchführen. Aktualisieren Sie schließlich Ihre Datenbank. Von nun an beschwert sich EF, wenn Sie ihm nicht mitteilen, welche Konfiguration Sie aktualisieren möchten:

Update-Database -ConfigurationTypeName MyNewContextConfiguration 

Getan.

Sie müssen sich nicht mit Enable-Migrations befassen, da "Configuration" bereits vorhanden ist und das Umbenennen Ihrer vorhandenen Konfigurationsklasse Probleme im Migrationsverlauf mit sich bringt.

Sie können auf verschiedene oder dieselbe Datenbank abzielen. Alle Konfigurationen teilen die __MigrationHistory-Tabelle.


4

Wenn weitere Datenbanken vorhanden sind, verwenden Sie die folgenden Codes in PowerShell

Add-Migration Starter -context EnrollmentAppContext 
  • 'Starter' ist der Migrationsname

  • 'EnrollmentAppContext' ist der Name meines App-Kontexts

Sie können PowerShell in VS folgendermaßen öffnen: Tools->NuGet Package Manager->Package Manager Console


1
Das hat mir geholfen. Vielen Dank! :)
noobprogrammer

3

So aktualisieren Sie den Datenbanktyp wie folgt: Code in PowerShell ...

Update-Database -context EnrollmentAppContext

* Wenn mehr als eine Datenbank vorhanden ist, verwenden Sie nur diese Codes, andernfalls nicht erforderlich.


0

EF 4.7 gibt tatsächlich einen Hinweis, wenn Sie Enable-Migrationen in mehreren Kontexten ausführen.

In der Assembly 'Service.Domain' wurde mehr als ein Kontexttyp gefunden.

To enable migrations for 'Service.Domain.DatabaseContext.Context1', 
use Enable-Migrations -ContextTypeName Service.Domain.DatabaseContext.Context1.
To enable migrations for 'Service.Domain.DatabaseContext.Context2',
use Enable-Migrations -ContextTypeName Service.Domain.DatabaseContext.Context2.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.