it-swarm.com.de

Keine erstmalige Erstellung mit Entity Framework-Migrationen

Ich versuche, Entity-Framework-Migrationen zum Laufen zu bringen. Ich habe Code-Migrationen erst aktiviert, einen Migrationsordner, eine Konfigurationsdatei und die Mig-Verlaufstabelle erstellt, jedoch keine Ersterstellung. Verpasse ich einen Schritt? Dies ist eine neue Datenbank, die von EF (4.3.1) erstellt wurde.

26
newbie_86

Dieses Verhalten ist standardmäßig nicht vorhanden, aber es steht Ihnen leicht in vielen verschiedenen Formen zur Verfügung.

  1. Sie können context.Database.CreateIfNotExists(); beim Start der Anwendung aufrufen.

  2. Sie können eine der integrierten DatabaseInitializers verwenden. Der CreateDatabaseIfNotExists-Initialisierer ist in EntityFramework integriert und muss nur zu Ihrem Projekt hinzugefügt werden.

  3. Sie können Ihren eigenen benutzerdefinierten Datenbankinitialisierer erstellen, der die Option # 1 enthält. Beispiel: Erste Migrationen und Initialisierung des Codes

Sie können DatabaseInitializers entweder per Code oder über eine Konfigurationsdatei in Ihr Projekt einfügen.

EntityFramework-Datenbankinitialisierer über Code einschließen:

Beim Start der Anwendung können Sie den DatabaseInitializer folgendermaßen einrichten:

System.Data.Entity.Database.SetInitializer<DairyMmmContext>(new System.Data.Entity.CreateDatabaseIfNotExists<DairyMmmContext>());

HINWEIS: Dieser Code hat sich im Laufe des Entityframeworks mehrmals geändert! Dieses Beispiel bezieht sich auf EF 4.3, die derzeit über Nuget verfügbare Produktionsversion.

EntityFramework-Datenbankinitialisierer über Konfigurationselement einschließen:

<configuration>
  <entityFramework>
    <contexts>
      <context type="MyNamespace.MyEFDataContext, AssemblyName">
        <databaseInitializer
          type="System.Data.Entity.CreateDatabaseIfNotExists`2[[MyNamespace.MyEFDataContext, AssemblyName],
               [MyNamespace.Migrations.Configuration,  AssemblyName]], EntityFramework" />
      </context>
    </contexts>
  </entityFramework>
</configuration>

Sie werden feststellen, dass dies bei dieser Konfiguration etwas "unansehnlich" sein kann. Sie müssen AssemblyName oben durch den Namen der Assembly ersetzen, in der Sie Ihre Entityframework-Elemente gespeichert haben, MyNamespace.MyEFDataContext durch den vollständig qualifizierten Namen Ihres Entitätsframework-Datenkontexts ersetzen und MyNamespace.Migrations.Configuration durch den vollständig qualifizierten Namen in Ihrer Konfigurationsklasse ersetzen (standardmäßig in der Migration Ordner in Ihrem Projekt).

EDIT: Bearbeitet, um auf zusätzliche Kommentare zu antworten

Eine Migration ist eine Änderung von einer Schemadefinition zu einer anderen Schemadefinition. Das Erstellen der leeren Datenbank ist keine Migration (aber alles danach). Es gibt keine Migrationsquelldatei in Ihrem Projekt, um nur eine leere Datenbank zu erstellen, die vom Initialisierer im Code ausgeführt wird.

Wenn Sie bereits den Initialisierer DropCreateDatabaseAlways verwenden, sollte dies der Fall sein. Mir ist jedoch aufgefallen, dass Sie den Initialisierer im Code festlegen. Dies bedeutet, dass ein Timing-Problem auftreten kann (das Festlegen des Initialisierers, nachdem Ihr Kontext den Punkt des Aufrufens von Initialisierern bereits überschritten hat).

Sie können entityframework dazu zwingen, Ihren Initialisierer an beliebiger Stelle im Code mit context.Database.Initialize(true); auszuführen (Der Parameter ist true/false, um die Initialisierung unabhängig vom aktuellen Status zu erzwingen). Dadurch würde Ihre Datenbank jedes Mal gelöscht und neu erstellt.

Sie können aber auch sicherstellen, dass Ihr Initialisierer so früh wie möglich im Lebenszyklus Ihrer Anwendung eingerichtet ist (bevor Sie eine einzelne Instanz Ihres Kontextes erstellt haben).

21
BenSwayne

"Initial Create" wird NICHT automatisch erstellt! Sie müssen das selbst erstellen. Einige Tutorials von EF sind verwirrend und ich hatte das gleiche Missverständnis wie Sie.

Was musst du machen:

-Add-Migration InitialModel

Wenn Sie Ihre Datenbanktabellen und Ihr Domänenmodell bereits erstellt haben, gilt Folgendes: 

-Add-Migration InitialModel -IgnoreChanges

Ab diesem Zeitpunkt ist Ihr Code mit der Datenbank synchron. Jedes Mal, wenn Sie den Code ändern, können Sie Add-Migration verwenden, um die Änderungen zu Ihrer Datenbank hinzuzufügen.

17
Mosh

Der Artikel/Tutorial hier hier (auf Microsoft.com) Beschreibt den Grund dafür, dass eine initialeCreate-Migration nicht vorhanden ist. Die Migration wird nur hinzugefügt, wenn die Datenbank bereits vorhanden ist. Andernfalls wird die erste Migration als 'initialCreate' ausgeführt, da es nicht sinnvoll ist, eine Migration zu einer Datenbank zu erstellen, die noch nicht vorhanden ist.

Hier ist der relevante Absatz:

Führen Sie den Befehl "Enable-Migrations" in der Package Manager Console aus Dieser Befehl hat unserem Projekt einen Migrationsordner hinzugefügt. Dieser neue Ordner enthält zwei Dateien:

Die Konfigurationsklasse. Mit dieser Klasse können Sie konfigurieren, wie sich Migrationen für Ihren Kontext verhalten. Für diese exemplarische Vorgehensweise verwenden wir einfach die Standardkonfiguration . Da es in Ihrem Projekt nur einen einzigen Code First-Kontext gibt, hat Enable-Migrations automatisch den Kontexttyp ausgefüllt, für den diese Konfiguration gilt.

Eine InitialCreate-Migration. Diese Migration wurde generiert, da bereits Code First eine Datenbank für uns erstellt hatte, bevor Migrationen aktiviert wurden. Der Code in dieser Gerüstmigration stellt die Objekte dar, die bereits in der Datenbank erstellt wurden. In unserem Fall ist dies die Blogtabelle mit einer BlogId- und einer Namensspalte. Der Dateiname enthält einen Zeitstempel, um die Bestellung zu erleichtern.

Wenn die Datenbank noch nicht erstellt wurde, wäre diese InitialCreate-Migration nicht zum Projekt hinzugefügt worden. Wenn wir zum ersten Mal Add-Migration aufrufen, wird der Code zum Erstellen dieser Tabellen für eine neue Migration eingerichtet.

9
wow0609

Ich bin nicht sicher, dass es dasselbe ist, aber ich hatte ein ähnliches Problem. Ich denke, mein Problem war auf die Tatsache zurückzuführen, dass ich keine Verbindungszeichenfolge aus der Konfigurationsdatei verwende, um meine Verbindungszeichenfolge abzurufen.

Durch das Startprojekt in der Lösung und das Projet-Combo in der Package Manager Console konnte ich die erste Migration generieren.

Stellen Sie außerdem sicher, dass Sie eine Verbindungszeichenfolge mit dem Namen Ihrer dbContext-Klasse haben, damit der Package Manager sie finden kann.

4
jjslagace

Ich weiß, das ist alt, aber es gibt keine akzeptierte Antwort und ich hatte das gleiche Problem.

Der Trick ist der Befehl "Enable-Migrations". Wie gesagt, hier gibt es einen Befehl Enable-Migrations - EnableAutomaticMigrations. Was es macht, beginnt die Migration genau dort, wo Sie sind.

Wenn Sie möchten, dass die erste Migration eine Datenbank erstellt, führen Sie einfach Enable-Migrations aus (ohne --EnableAutomaticMigrations).

Und denken Sie daran, den Initialisierer einzustellen:

            Database.SetInitializer(new MigrateDatabaseToLatestVersion<LicenseContext, Configuration>());
0

Ich verwende EF 6 RC1 und bin auf dieses Problem gestoßen, bei dem beim Ausführen von Enable-Migrations weder InitialCreate noch __MigrationHistory erstellt wurden.

Direkt nach dem Upgrade von EF 5 auf EF 6 habe ich Enable-Migrations ausgeführt und aus irgendeinem Grund eine __MigrationHistory-Tabelle mit dem EF 5-Schema erstellt. Deshalb habe ich sie und mein Migrationsverzeichnis gelöscht und versucht, von vorne zu beginnen.

Bei jedem Löschen des Migrationsverzeichnisses wurde jedoch kein InitialCreate oder __MigrationHistory erstellt. Ich habe versucht, die Datenbank zu löschen und neu zu erstellen und Visual Studio 2012 ohne Erfolg neu zu starten. Ich gab den Tag auf und versuchte es am nächsten Morgen noch einmal - nachdem ich meinen Computer etwa 8 Stunden sitzen gelassen hatte, wurde der InitialCreate erstellt. Ich vermute, es muss irgendwo einen Cache geben, der einen wirklich langen Timeout hat. Ich vermute auch, dass ein Neustart den Cache leeren könnte, aber ich habe das nicht versucht.

In jedem Fall können Sie PM> Add-Migration InitialCreate verwenden, um diesen Schritt manuell auszuführen.

Trotzdem habe ich immer noch keine __MigrationHistory-Tabelle erhalten. Offenbar hat sich EF 6 von der Erstellung während des Befehls "Enable-Migrations" geändert und stattdessen nur noch während des Befehls "Update-Database" erstellt. Und da mein Schema zu diesem Zeitpunkt bereits erstellt wurde, musste ich es abmontieren und manuell neu erstellen:

PM> Update-Database -TargetMigration:0
PM> Update-Database

Ich habe auch nach dem ersten Befehl angehalten, um den Status der Datenbank zu überprüfen, um sicherzustellen, dass ich den korrekten aktualisiert habe, da entsprechend - die Datenbankverbindungszeichenfolge abhängig von der Konfiguration abgerufen oder automatisch generiert wird, sofern dies nicht der Fall ist Rechts konfiguriert, gibt es keine Garantie, dass Sie auf die Datenbank oder die Instanz von SQL Server zugreifen, die Sie beabsichtigen.

Nachdem beide Befehle ausgeführt wurden, wurde eine __MigrationHistory-Tabelle erstellt. Sie wurde jedoch nicht als Systemtabelle erstellt (was ich eigentlich nicht wollte), also ist alles gut. Nicht dasselbe Problem wie das OP, aber hoffentlich wird dies für andere hilfreich sein.

Verweise:

0
NightOwl888