EF 4.3 Auto-Migrationen mit mehreren DbContexten in einer Datenbank
Ich versuche, EF 4.3-Migrationen mit mehreren code-first-DbContexts. Meine Anwendung ist getrennt in mehrere plugins, die möglicherweise Ihre eigenen DbContext in Bezug auf Ihre domain. Die Applikation soll die Verwendung einer einzigen sql-Datenbank.
Wenn ich versuche auto zu migrieren, die Zusammenhänge, in eine leere Datenbank ist nur dann erfolgreich, für den ersten Kontext. Jedem anderen Kontext braucht die AutomaticMigrationDataLossAllowed-Eigenschaft auf true festgelegt, aber es wird dann versucht, zum löschen der Tabellen des vorhergehenden.
Also meine Frage ist:
- Wie kann ich sagen, die migration, Konfiguration, nur um sich nach der definierten Tabellen im entsprechenden Kontext, und lassen Sie alle anderen alleine?
- Was ist der richtige workflow, um sich mit mehreren DbContexts mit auto-migration in einer einzigen Datenbank?
Danke!
Kommentar zu dem Problem
Das ist eine sehr interessante Frage. Ich Frage mich, ob mehrere Rahmen die Unterstützung war Teil des Migrations-use-cases.
Ich bezweifle stark multi-Kontexte der Arbeit mit auto-Migrationen, es ist entworfen, um zu aktualisieren, die db zu schauen, wie der Kontext, egal was. Sie können mehr Glück haben die Entwicklung des plugins mit der manuellen Migrationen, gegen separate Datenbanken zu generieren, die Migrationen dann alle zu gleichen db.
In der Zwischenzeit habe ich spähte in die EF 4.3-Baugruppen, und ich habe auch Zweifel, dass die migration framework bewältigen können mehrere Kontexte. Aber es gibt keinen technischen Grund, der mir einfällt. Mit einem EDM-Modell an der Stelle könnte man diff, die gegen die Datenbank finden Sie die vorhandenen Tabellen Tabellen erstellen oder ändern, und lassen Sie die Löschung Szenario durch manuelle Migration der Benutzer.
InformationsquelleAutor der Frage Joachim Rosskopf | 2012-02-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Code First-Migrationen wird davon ausgegangen, dass es nur ein Migrationen Konfiguration pro Datenbank (und ein Kontext pro-Konfiguration).
Ich denken kann zwei mögliche Lösungen:
Erstellen einer aggregierten Rahmen beinhaltet, dass alle Personen jeden Kontext und einen Verweis auf diese "super" - Kontext aus Ihrer Migrationen configuration-Klasse. Auf diese Weise werden alle Tabellen erstellt, in der Benutzer-Datenbank, aber die Daten werden nur in diejenigen, die Sie installiert haben plugins für.
Verwenden Sie separate Datenbanken für jeden Kontext. Wenn Sie haben gemeinsame Einheiten zwischen den Kontexten, fügen Sie eine benutzerdefinierte migration und ersetzen Sie die
CreateTable(...)
Anruf mit einemSql("CREATE VIEW ...")
aufrufen, um die Daten aus der Entität "entstehen" - Datenbank.Ich würde versuchen, #1, weil es hält sich noch alles in einer einzigen Datenbank. Sie könnten ein separates Projekt in der Projektmappe enthalten Migrationen und diese "super" - Kontext. Fügen Sie einfach das Projekt, Referenz, alle Ihre plugins " - Projekte, erstellen Sie einen Kontext, der alle Entitäten, dann rufen Sie Ermöglichen-Migrationen auf das neue Projekt. Dinge, die funktionieren sollte, wie erwartet, nach, dass.
InformationsquelleAutor der Antwort bricelam
Hier ist was Sie tun können. sehr einfach.
Können Sie erstellen, Configration-Klasse für jede von Ihrem Kontext.
e.g
Nun fügen Sie die migration. Sie brauchen nicht, um die migration zu ermöglichen, da Sie schon mit den 2 oben eingestuft.
Dadurch wird die migration-Skript für context1. Ihr können, wiederholen Sie dies auch für andere Kontexte.
Aktualisieren Sie Ihre Datenbank
Diese können in beliebiger Reihenfolge durchgeführt werden. Außer Sie brauchen, um sicherzustellen, dass jeder configration ist genannt in der Reihenfolge.
InformationsquelleAutor der Antwort Anuj Pandey
Ich habe eine funktionierende Website mit mehreren Kontexten Verwendung von Migrationen. Jedoch, Sie brauchen, um eine separate Datenbank pro Kontext, und es ist alles angetrieben von einem *Configuration-Klasse im Migrations-namespace des Projekts, so zum Beispiel CompanyDbContext Punkte zu Unternehmen.sdf mit CompanyConfiguration.
update-database -configurationtypename CompanyConfiguration
. Ein weiterer LogDbContext Punkte zu Melden.sdf mit LogConfiguration, etc.Gegeben dies funktioniert, haben Sie versucht, erstellen 2 Kontexte verweist auf die gleiche Datenbank zu und erzählte dem modelbuilder zu ignorieren die anderen im Rahmen der Liste der Tabellen?
Seit der Migration die Arbeit mit dem ModelBuilder, könnte dies den job zu erledigen.
Beschissen alternative ist zu vermeiden, mit Automatische Migrationen, erstellen Sie eine migration jedes mal, und dann manuell zu durchforsten, und entfernen Sie unerwünschte Aussagen, dann laufen Sie, obwohl es nichts hindert Sie von der Erstellung einer einfachen tool, schaut auf die Zusammenhänge und generiert Aussagen und tut der Migrations-Korrekturen für Sie.
InformationsquelleAutor der Antwort Chris Moschini
Ok, ich habe zu kämpfen mit diesem für einen Tag jetzt, und hier ist die Lösung für diejenigen, die die Antwort...
Gehe ich davon aus, dass die meisten Leute diesen Beitrag Lesen, sind hier, weil Sie eine große DbContext-Klasse mit einer Menge von DbSet<> "Eigenschaften" und es dauert eine lange Zeit zum laden. Sie dachte wahrscheinlich, um sich selbst, alle Achtung, das macht Sinn, ich sollte Sie trennen den Zusammenhang, da ich nicht mit allen dbsets auf einmal, und ich nur laden Sie eine "Teil -" Kontext auf der Grundlage der situation, wo ich es brauche. So Sie zu trennen, nur um herauszufinden, dass Code First-Migrationen nicht unterstützen, Ihren Weg des revolutionären Denkens.
Also Ihr Erster Schritt gewesen sein muss, Aufteilung der Kontexte, dann werden Sie Hinzugefügt der MigrationConfiguration-Klasse für jede neue Kontexte Hinzugefügt Sie die Verbindungszeichenfolgen namens genau das gleiche wie Ihre neue Kontext-Klassen.
Dann Sie versucht mit den neu aufgeteilt Kontexte ein, indem ein, indem Sie den Add-Migration Context1 dann tut Update-Datenbank -Verbose...
Alles schien zu funktionieren, aber dann bemerken Sie, dass jede spätere Migration gelöscht werden alle Tabellen aus der Vorherigen migration, und nur Links die Tabellen aus der letzten migration.
Dies ist, weil die aktuellen Migrationen Modell erwartet Single DbContext-pro-Datenbank, und es muss ein Spiegel sein match.
Was ich auch schon versucht, und jemand schlug vor, hier dies zu tun, ist erstellen Sie eine einzelne SuperContext, die die Db setzt. Erstellen Sie eine einzelne Migration Configuration-Klasse, und führen Sie dieses in. Lassen Sie Ihre partielle Kontext-Klassen im Ort, und versuchen Sie zu Instanziieren und zu verwenden. Die EF beschwert sich, dass die Backing-Modell hat sich geändert. Wieder, dies ist, weil die EF vergleicht die partielle dbcontext dem All-Sets Kontext Signatur, die war übrig von Ihrer Super-Kontext migration.
Dies ist ein großer Fehler meiner Meinung nach.
In meinem Fall, habe ich beschlossen, dass LEISTUNG wichtiger ist als Migrationen. Also, was ich am Ende tun, ist, nachdem ich lief in der Super Rahmen und hatte alle Tische im Ort, ich ging in die Datenbank und Manuell gelöscht _MigrationHistory Tabelle.
Nun, ich kann instanziieren und verwenden Sie meine Teilweise Kontexten ohne EF beschweren sich über Sie. Es nicht die MigrationHistory Tisch und bewegt gerade auf, dass ich eine "Teilweise" Sicht auf die Datenbank.
Der trade-off ist natürlich, dass alle änderungen am Modell werden manuell an der Datenbank, also seien Sie vorsichtig.
Er arbeitete für mich aber.
InformationsquelleAutor der Antwort Rick Ellis
Wie oben erwähnt von Brice, die praktische Lösung ist, um 1 super DbContext pro Anwendung/Datenbank.
Dass nur 1 DbContext für eine gesamte Anwendung zu sein scheint, einen entscheidenden technischen und methodischen Nachteil, denn es betrifft die Modularität, unter anderem. Auch, wenn Sie mithilfe von WCF Data Services Sie können nur 1 DataService pro-Anwendung, da eine DataService-Karte kann nur 1 DbContext. Also dadurch verändert sich die Architektur deutlich.
Auf der plus-Seite, ein kleiner Vorteil ist, dass alle im Zusammenhang mit der Datenbank-Migrations-code wird zentralisiert.
InformationsquelleAutor der Antwort user1718625
Ich kam gerade über diesem problem und erkannte den Grund, den ich aufgeteilt hatte, Sie in verschiedenen zusammenhängen wurde rein zu haben gruppieren verwandter Modelle in handhabbare Teile und nicht für irgendwelchen anderen technischen Gründen. Sondern ich habe erklärt, meinen Kontext als eine partielle Klasse und nun verschiedene code-Dateien mit den unterschiedlichen Modellen in der Sie Sie hinzufügen können DbSets der DbContext.
Diese Weise die automigration Magie noch funktioniert.
InformationsquelleAutor der Antwort Alan Macdonald
Habe ich es arbeiten mit manuellen Migrationen, aber man kann nicht downgraden, da es nicht discrimitate zwischen den Konfigurationen in der __MigrationHistory Tabelle. Wenn ich versuche, und downgrade dann behandelt er die Migrationen von den anderen Konfigurationen als Automatik und da ich nicht zulassen Datenverlust führt. Wir werden immer nur, es zu aktualisieren, aber so funktioniert es für unsere Zwecke.
Scheint einiges ommision obwohl, ich bin sicher, es würde nicht schwer sein, Sie zu unterstützen, vorausgesetzt, es wurde keine überlappung zwischen DbContexts.
InformationsquelleAutor der Antwort mackie
Sicherlich die Lösung sollte eine Modifikation durch das EntityFramework team zum ändern der API-Unterstützung der direkten Modifikation der _MigrationHistory Tabelle, um eine Tabelle Namen Ihrer Wahl wie _MigrationHistory_Context1 so, dass Sie mit der änderung der unabhängigen DbContext Personen. So sind Sie alle separat behandelt werden, und die bis an den Entwickler, um sicherzustellen, dass die Namen der Einheiten nicht kollidieren.
Scheint, wie es gibt eine Menge Leute, die teilen meine Meinung, dass eine doppelte DbContext-mit Referenzen zu den übergeordneten Entitäten ist eine falsche nicht-enterprise-freundlichen Weg zu gehen über die Dinge. Doppelte DbContexts kläglich für modular (PRISMA oder ähnlich) - basierte Lösungen.
InformationsquelleAutor der Antwort Westy
Ich will, dass die Leute wissen, dass die Antwort mit diesem unten ist das, was für mich gearbeitet, aber mit einer Einschränkung: benutzen Sie nicht die MigrationsNamespace Linie.
Jedoch, ich hatte bereits die 2 Datenbanken eingerichtet, die mit Ihren eigenen Kontexten definiert, so fand ich mich immer die Fehlermeldung "YourProject.Modelle namespace bereits ContextNamespace1 definiert". Dies war, weil die "MigrationsNamespace = "YourProject.Modelle.ContextNamespace2";" war, die den dbcontext definiert werden, unter der YourProjects.Modelle namespace zweimal nach ich habe versucht die Init (einmal in der migration Context1Init-Datei und einmal, wo ich hatte es vorher definiert).
So, ich fand, dass das, was ich zu tun hatte an diesem Punkt war der start meiner Datenbank und Migrationen von Grund auf neu (zum Glück hatte ich keine Daten, die ich behalten musste) über und folgt den Anweisungen hier:
http://pawel.sawicz.eu/entity-framework-reseting-migrations/
Dann änderte ich den code, damit Sie NICHT die MigrationsNamespace Linie.
Dann lief ich in den Add-Migration -Konfiguration Configuration1 Context1Init Befehl erneut aus, und die Update-Datenbank -Konfiguration Configuration1 Linie wieder (für meinen 2ten Rahmen zu), und schließlich scheint alles zu funktionieren nun Super.
InformationsquelleAutor der Antwort Notso