Code-First für Entity Framework: Die Migration schlägt mit der Update-Datenbank fehl und erzwingt eine unnötige (?) Add-Migration

73

Ich habe einen lustigen Effekt mit Migration (EF 5.0) und Code-First:

Ich habe einige Modelle mit GUID-Primärschlüsseln erstellt. (Übrigens: Es ist wichtig für mich, dass SQL Server verwendet NEWSEQUENTIALID(), was in der aktuellen Version der Standardwert zu sein scheint.)

Irgendwann habe ich Migrationen aktiviert. Ich habe der anfänglichen Migration etwas Code hinzugefügt, dies ist meistens .Index()nach Bedarf.

Wenn ich die Datenbank lösche und update-database aufrufe, wird folgende Fehlermeldung angezeigt:

Die Datenbank kann nicht aktualisiert werden, um mit dem aktuellen Modell übereinzustimmen, da Änderungen ausstehen und die automatische Migration deaktiviert ist. Schreiben Sie entweder die ausstehenden Modelländerungen in eine codebasierte Migration oder aktivieren Sie die automatische Migration. Setzen Sie DbMigrationsConfiguration.AutomaticMigrationsEnabled auf true, um die automatische Migration zu aktivieren. Mit dem Befehl Add-Migration können Sie die ausstehenden Modelländerungen in eine codebasierte Migration schreiben.

Ich habe es versucht AutomaticMigrationsEnabled = true, was funktioniert hat, ohne etwas zu ändern oder hinzuzufügen!

Aber da ich nicht will AutomaticMigrationsEnabled, habe ich auch versucht, die Datenbank erneut zu löschen, aufgerufen update-databaseund dann add-migration. Am Ende hatte ich eine zusätzliche Migration, die anscheinend nichts ändert (siehe unten). Ich habe auch versucht, diese Zeilen am Ende der anfänglichen Migration hinzuzufügen - dies ändert jedoch nichts.

Eines der Modelle:

[Table(Speaker.TABLENAME)]
public class Speaker : BaseModel
{
    public const String TABLENAME = "Speaker";

    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

    [Required]
    [MaxLength(50, ErrorMessage = "Name must be 50 characters or less")]
    public string Name { get; set; }
}

Der anfängliche Migrationscode:

public partial class InitialCreate : DbMigration
{
    public override void Up()
    {
        // [...]
        CreateTable(
            "dbo.Speaker",
            c => new
                {
                    Id = c.Guid(nullable: false, identity: true),
                    Name = c.String(nullable: false, maxLength: 50),
                })
            .PrimaryKey(t => t.Id)
            .Index(t => t.Name, true, false);   // added manually: unique Name
        // [...]
    }
}

internal sealed class Configuration : DbMigrationsConfiguration<MyProject.Repositories.DBContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(MyProject.Repositories.DBContext context)
    {
        // ...
    }
}

Unten ist der Code, der durch Add-Migration erstellt wurde: Er scheint nichts Neues zu bewirken - vielleicht fehlt mir etwas?

public partial class UnneccessaryMigration : DbMigration
{
    public override void Up()
    {
        // isn't this the exact same code from InitialMigrations?
        AlterColumn("dbo.Speaker", "Id", c => c.Guid(nullable: false, identity: true));
        // ...
    }

    public override void Down()
    {
        //...
        AlterColumn("dbo.Speaker", "Id", c => c.Guid(nullable: false));
    }
}

Ich bin also neugierig: Was habe ich getan, um Migrationen zu desorientieren? Und was kann ich tun, damit es mit nur einer ersten Migration funktioniert?

Lösung : Die folgende Problemumgehung hat es für mich getan:

  1. Ich habe die Datenbank und alle hier beschriebenen Migrationen gelöscht: https://stackoverflow.com/a/11679386/3168401
  2. Enable-Migrations + Add-Migration Initial ausgeführt
  3. Meine handgemachten .Index () Änderungen wurden in die Datei eingefügt. Jetzt funktioniert Update-Database wieder - auch wiederholt beim Löschen der Datenbank.
Da ich bin
quelle

Antworten:

111

Ich habe auch versucht, die Datenbank erneut zu löschen, Update-Datenbank genannt und dann Migration hinzugefügt. Am Ende hatte ich eine zusätzliche Migration, die anscheinend nichts ändert (siehe unten).

Aufgrund der obigen Details denke ich, dass Sie als letztes das Letzte getan haben. Wenn Sie Update databasezuvor ausgeführt haben Add-migration, wird die Datenbank nicht mit Ihren Migrationsschemata aktualisiert. Zuerst müssen Sie die Migration hinzufügen und dann den Befehl update ausführen.

Probieren Sie sie in dieser Reihenfolge mit der Paketmanager-Konsole aus.

PM> Enable-migrations //You don't need this as you have already done it
PM> Add-migration Give_it_a_name
PM> Update-database
Kaf
quelle
2
Vielleicht irre ich mich in diesem Punkt, aber ich möchte in der Lage sein, die Datenbank bei Bedarf neu zu erstellen. Tut die anfängliche Migration nicht genau das? Bevor ich auf den oben beschriebenen Effekt stieß, funktionierte das Erstellen der Datenbank mit update-database einwandfrei. Und sobald ich den Migrationsschritt "Kid of Blank" hinzufüge, funktioniert es auch.
Ich
Wenn keine Datenbank vorhanden ist, erstellt der Befehl update database die Datenbank neu und aktualisiert sie auch mit verfügbaren Migrationen. Wenn Sie die Datenbank aktualisieren müssen, müssen Sie sie add-migrationzuerst ausführen update database, um diese Änderungen hinzuzufügen.
Kaf
Ich bin gespannt, warum die "nutzlose" Migration überhaupt hinzugefügt wird.
Jim Aho
Ich hatte ähnliche Probleme. Die Ausgabe der obigen Befehle führte dazu, dass Ausnahmen ausgelöst wurden. Ich startete Visual Studio neu und führte sie erneut aus, als es gestartet wurde, und es war in Ordnung.
Lismore
9

Entity Framework hat einige Probleme mit Identitätsfeldern.

Sie können der vorhandenen Tabelle keine GUID-Identität hinzufügen

Migrationen: Erkennt keine Änderungen an DatabaseGeneratedOption

Beim Reverse Engineering werden GUID-Schlüssel mit der Standardeinstellung NEWSEQUENTIALID () nicht als im Geschäft generierte Identitäten markiert

Keines davon beschreibt Ihr Problem genau und die Down () -Methode in Ihrer zusätzlichen Migration ist interessant, da sie anscheinend versucht, IDENTITY aus der Spalte zu entfernen, wenn Ihre CREATE TABLE in der ersten Migration es zu setzen scheint!

Wenn Sie die SQL verwenden Update-Database -Scriptoder Update-Database -Verboseanzeigen, die mit diesen AlterColumnMethoden ausgeführt wird , werden Sie außerdem feststellen, dass die SQL in Upund identisch Downist und tatsächlich nichts tut. IDENTITY bleibt unverändert (für die aktuelle Version - EF 6.0.2 und niedriger) - wie in den ersten beiden Ausgaben beschrieben, auf die ich verlinkt habe.

Ich denke, Sie sollten den redundanten Code in Ihrer zusätzlichen Migration löschen und vorerst mit einer leeren Migration leben. Und Sie können die zu behandelnden Themen abonnieren / abstimmen.

Verweise:

Die Option IDENTITY ändern hockt nicht

Schalten Sie die Identität mit einem benutzerdefinierten Migrationsvorgang ein / aus

Colin
quelle
Vielen Dank für diese Hinweise! Ich werde diese Themen positiv bewerten. Im Moment konnte ich mein Problem umgehen, indem ich den Wohole-Migrationsordner, die Datenbank und das Restartet löschte: Enable-Migrations, Add-Migration, und dann mein .Index () erneut hinzufügte. Das scheint zu funktionieren.
Ich
3

Versuche dies:

PM> Enable-migrations -force
PM> Add-migration MigrationName
PM> Update-database -force
Muhammad Awais
quelle
1

Für mich habe ich es wie folgt gelöst: In Visual Studio 2015: Klicken Sie im Menü Ansicht auf Andere Windows, dann auf Package Manager Console und führen Sie die folgenden Befehle aus:

PM> enable-migrations

Migrationen wurden bereits im Projekt 'mvcproject' aktiviert. Verwenden Sie den Parameter -Force, um die vorhandene Migrationskonfiguration zu überschreiben.

PM> enable-migrations -Force

Überprüfen, ob der Kontext auf eine vorhandene Datenbank abzielt ... Code First Migrations für Projekt mvcproject aktiviert.

Fügen Sie dann den Migrationsnamen unter dem Migrationsordner hinzu, um die Klasse hinzuzufügen, die Sie im Projektmappen-Explorer benötigen, indem Sie den folgenden Befehl ausführen

PM>Add-migration AddColumnUser

Aktualisieren Sie abschließend die Datenbank

PM> update-database 
Abdullah
quelle
Upvoted, um mir tatsächlich zu sagen, wie ich die Eingabeaufforderung starten soll, an der ich diese Befehle eingeben muss.
Philip Stratford
0

Wenn Sie VS2019, MVC5 verwenden, suchen Sie im Ordner Migrations nach der Datei Configuration.cs. Bearbeiten: AutomaticMigrationsEnabled = true

    - -
Sam Patirage
quelle
0

Als Antwort auf Ihre allgemeine Frage von

Ich bin also neugierig: Was habe ich getan, um Migrationen zu desorientieren? Und was kann ich tun, damit es mit nur einer ersten Migration funktioniert?

Ich habe gerade die gleiche Fehlermeldung wie Sie erhalten, nachdem ich mehrere Zweige zusammengeführt habe und die Migrationen über den aktuellen Status der Datenbank verwirrt waren. Am schlimmsten war, dass dies nur auf dem Client-Server geschah, nicht auf unseren Entwicklungssystemen.

Beim Versuch herauszufinden, was dort geschah, stieß ich auf diesen hervorragenden Microsoft-Leitfaden:

Microsoft-Handbuch zu Code First Migrations in Teamumgebungen

Während dieser Leitfaden geschrieben wurde, um Migrationen in Teams zu erklären, gibt er auch die beste Erklärung, die ich gefunden habe, wie die Migrationen intern funktionieren, was möglicherweise zu einer Erklärung für das Verhalten führt, das Sie sehen. Es lohnt sich, sich eine Stunde Zeit zu nehmen, um all das für alle zu lesen, die mit EF6 oder niedriger arbeiten.

Für alle, die nach dem Zusammenführen von Migrationen durch diese Fehlermeldung auf diese Frage gebracht wurden, hat der Trick, eine leere Migration mit dem aktuellen Status der Datenbank zu generieren , die Probleme für mich gelöst. Lesen Sie jedoch unbedingt die gesamte Anleitung, um zu wissen, ob diese Lösung vorliegt angemessen in Ihrem Fall.

tomRedox
quelle
0

Ich hatte dieses Problem und die obigen Vorschläge haben nicht geholfen. Ich habe festgestellt, dass die Add-Migration den aktuellen Status liest und eine Signatur des aktuellen Modells erstellt. Sie müssen Ihr Modell ändern, bevor Sie es ändern. Die Reihenfolge ist also.

  1. Modell ändern
  2. Führen Sie die Add-Migration aus

Ich habe das Gegenteil getan und die Migration hinzugefügt, bevor ich mein Modell geändert habe (das leer war, also habe ich die neuen Spalten hinzugefügt) und dann meinen Code ausgeführt.

Hoffe das hilft.

Steve Sampson
quelle
0

Wenn Sie Ihr Kontextmodell zuerst als Code basierend auf der vorhandenen Datenbank festlegen, müssen Sie für die Migration Folgendes festlegen:

Add-Migration InitialCreate –IgnoreChanges
Update-database -force

und ändern Sie dann Ihr Kontextmodell und setzen Sie:

Add-migration RemoveIspositive
Update-database -force
Ata Hoseini
quelle
0

Ich verstehe, dass dies ein sehr alter Thread ist. Ich wollte jedoch mitteilen, wie ich auf die Nachricht in meinem Szenario gestoßen bin und ob sie anderen helfen könnte

  1. Ich habe Add-Migration <Migration_name>auf meinem lokalen Computer eine erstellt. Ist das update-databasenoch nicht gelaufen .
  2. In der Zwischenzeit gab es eine Reihe von Commits im übergeordneten Zweig, die ich zusammenführen muss. Die Zusammenführung hatte auch eine Migration und als ich Konflikte behoben habe, hatte ich zwei Migrationen, die meinem Projekt hinzugefügt, aber nicht über ausgeführt wurden update-database.
  3. Jetzt verwende ich nicht enable-migrations -forcein meiner Anwendung. Meine bevorzugte Methode ist vielmehr, den update-database -scriptBefehl auszuführen , um die von mir benötigten Zielmigrationen zu steuern.
  4. Als ich den obigen Befehl versuchte, wurde der betreffende Fehler angezeigt.

Meine Lösung war das Ausführen update-database -Script -TargetMigration <migration_name_from_merge>und dann update-database -Script -TargetMigration <migration_name>das Ausführen von 2 Skripten, die ich manuell auf meiner lokalen Datenbank ausführen konnte.

Unnötig zu erwähnen, dass die Erfahrung oben auf meinem lokalen Computer liegt.

Phani
quelle