Ich versuche, eine leicht verständliche DBContext
-Klasse zu schreiben, die eine benutzerdefinierte Verbindungszeichenfolge akzeptiert, Migrationen ausführen kann und die es mir ermöglicht, Migrationen mit dem Paket-Manager zu generieren.
Ich gehe anscheinend im Kreis herum.
Ich konnte es mit Code arbeiten lassen, der sich für mich schrecklich anfühlt. Ich dokumentierte dies in meiner Antwort auf Diese Frage zu Verbindungszeichenfolge und Migrationen.
Radeks Antwort sieht viel besser aus als meine, aber ich finde, dass wenn ich es implementiere und dann versuche, eine Migration im Paketmanager zu erstellen, bekomme ich die Nachricht
Der Zielkontext 'DataLayer.Context' ist nicht konstruierbar. Fügen Sie einen Standardkonstruktor hinzu oder stellen Sie eine Implementierung von IDbContextFactory bereit.
Wo DataLayer.Context
meine Kontextklasse ist.
Ich möchte keine Implementierung von IDbContextFactory
bereitstellen (und Radeks Antwort scheint darauf hinzudeuten, dass sie nicht benötigt wird)
UPDATE:
Ich kann eine Migration generieren, wenn ich einen Konstruktor ohne Parameter einschließe. Zum Beispiel
%Vor%Für meine Context-Erstellung gebe ich den Namen der Verbindungszeichenfolge in app.config
%Vor%Endlich kann ich sowohl Migrationen generieren als auch Migrationen für Datenbanken ausführen, die der Benutzer auswählt.
JEDOCH: Wenn ich die Datenbank lösche und dann meine App starte, habe ich Probleme.
Der Initialisierungscode, den ich benutze, ist der obige Link
%Vor%Wenn ich die Datenbank lösche, wird eine neue erstellt, aber es hat keine Tabellen. Das liegt daran, dass mein Tabellenerstellungscode erst in meiner ersten Migration enthalten ist.
Der Code in der !context.Database.CompatibleWithModel(false)
-Kondition wird nicht ausgeführt.
Leider läuft der Code auch nicht beim zweiten Mal, wenn er das Metadatamodell haben sollte.
Versuchen Sie nun, die Migration zu starten ...
SADNESS: Nein mit Radeks benutzerdefiniertem Initialisierer bis jetzt.
Aus den Kommentaren von NSGaga habe ich die Anwendung verlassen, wenn ich die Verbindung ändere.
%Vor% (Hinweis: Ich habe keine Ahnung von Ihrem benutzerdefinierten Initialisierer, ich habe gerade gesehen, dass dies eine allgemeine Lösung für das connection caching
-Problem und Migrationsinitialisierer ist - sollte aber mit Variationen funktionieren)
Wenige Punkte:
1) Definieren Sie static
connection in Ihrem Kontext - und wenn Sie eine 'neue' festlegen, ändern Sie diese in die latest value
. Das hilft dabei, Dinge in Synchronisation zu halten - egal, wer auf den DbContext zugreift, hat den gleichen (er ist im Konzept ähnlich wie Factory
nur einfacher für die Augen,
2) Problem mit Migrations
ist - dass MigrateDatabaseToLatestVersion
intern die Verbindung (und die gesamte Konfiguration intern) in einem readonly
Feld zwischenspeichert - und auch wenn Sie es in Ihrem DbContext
oder was auch immer ändern Wenn Sie es draußen einstellen, wird es nicht mehr synchron sein .
Es gibt keine andere Möglichkeit, als einen "neuen Initialisierer" zu erstellen.
3) Was @Radek entdeckt hat, war tatsächlich die Lösung für dieses Problem - und im Einklang mit (2). Ich habe das Initialize(true)
einfach entfernt, weil es unnötig ist - das wird aufgerufen, wenn 'die Zeit stimmt'.
Damit kann ich jetzt flip
meine Verbindungen rund um die Uhr - und wie ich will.
(Das heißt, ich kann die Verbindung bei runtime
ändern - migriere / erstelle zwei oder mehr Datenbanken und verändere ständig die Verbindungen und arbeite gleichzeitig daran)
Und das ist der Code, den ich tatsächlich verwende, um zwischen Verbindungen zu wechseln ...
%Vor%Der Schlüssel ist
set initializer each time you set the connection
.
Der alte ist immer noch da - und die alte Verbindung (Sie können den Db nicht löschen, während die App läuft)
Nachdem ich viel herumgeschlurft bin, habe ich das zum Laufen gebracht:
%Vor%Hier ist die Konfigurationsklasse. Beachten Sie die deaktivierten AutomaticMigrations:
%Vor%Und hier ist die Hilfsklasse SqlCeConnection, in der der Datenbankspeicherort zur Laufzeit gesetzt werden kann:
%Vor%HTH
Tags und Links c# migration ef-code-first