wake-up-neo.com

Entity Framework Migrations benennt Tabellen und Spalten um

Ich habe ein paar Entitäten und ihre Navigationseigenschaften umbenannt und in EF 5 eine neue Migration generiert. Wie bei Umbenennungen in EF-Migrationen üblich, löschte es standardmäßig Objekte und erstellte sie neu. Das wollte ich nicht, also musste ich die Migrationsdatei von Grund auf neu erstellen.

    public override void Up()
    {
        DropForeignKey("dbo.ReportSectionGroups", "Report_Id", "dbo.Reports");
        DropForeignKey("dbo.ReportSections", "Group_Id", "dbo.ReportSectionGroups");
        DropForeignKey("dbo.Editables", "Section_Id", "dbo.ReportSections");
        DropIndex("dbo.ReportSectionGroups", new[] { "Report_Id" });
        DropIndex("dbo.ReportSections", new[] { "Group_Id" });
        DropIndex("dbo.Editables", new[] { "Section_Id" });

        RenameTable("dbo.ReportSections", "dbo.ReportPages");
        RenameTable("dbo.ReportSectionGroups", "dbo.ReportSections");
        RenameColumn("dbo.ReportPages", "Group_Id", "Section_Id");

        AddForeignKey("dbo.ReportSections", "Report_Id", "dbo.Reports", "Id");
        AddForeignKey("dbo.ReportPages", "Section_Id", "dbo.ReportSections", "Id");
        AddForeignKey("dbo.Editables", "Page_Id", "dbo.ReportPages", "Id");
        CreateIndex("dbo.ReportSections", "Report_Id");
        CreateIndex("dbo.ReportPages", "Section_Id");
        CreateIndex("dbo.Editables", "Page_Id");
    }

    public override void Down()
    {
        DropIndex("dbo.Editables", "Page_Id");
        DropIndex("dbo.ReportPages", "Section_Id");
        DropIndex("dbo.ReportSections", "Report_Id");
        DropForeignKey("dbo.Editables", "Page_Id", "dbo.ReportPages");
        DropForeignKey("dbo.ReportPages", "Section_Id", "dbo.ReportSections");
        DropForeignKey("dbo.ReportSections", "Report_Id", "dbo.Reports");

        RenameColumn("dbo.ReportPages", "Section_Id", "Group_Id");
        RenameTable("dbo.ReportSections", "dbo.ReportSectionGroups");
        RenameTable("dbo.ReportPages", "dbo.ReportSections");

        CreateIndex("dbo.Editables", "Section_Id");
        CreateIndex("dbo.ReportSections", "Group_Id");
        CreateIndex("dbo.ReportSectionGroups", "Report_Id");
        AddForeignKey("dbo.Editables", "Section_Id", "dbo.ReportSections", "Id");
        AddForeignKey("dbo.ReportSections", "Group_Id", "dbo.ReportSectionGroups", "Id");
        AddForeignKey("dbo.ReportSectionGroups", "Report_Id", "dbo.Reports", "Id");
    }

Ich versuche nur, dbo.ReportSections In dbo.ReportPages Und dann dbo.ReportSectionGroups In dbo.ReportSections Umzubenennen. Dann muss ich die Fremdschlüsselspalte auf dbo.ReportPages Von Group_Id In Section_Id Umbenennen.

Ich lösche die Fremdschlüssel und Indizes, die die Tabellen miteinander verbinden, benenne die Tabellen und die Fremdschlüsselspalte um und füge dann die Indizes und Fremdschlüssel erneut hinzu. Ich nahm an, dass dies funktionieren würde, aber ich erhalte einen SQL-Fehler.

Meldung 15248, Ebene 11, Status 1, Prozedur sp_rename, Zeile 215 Entweder ist der Parameter @objname nicht eindeutig, oder der beanspruchte @objtyp (COLUMN) ist falsch. Meldung 4902, Ebene 16, Status 1, Zeile 10 Das Objekt "dbo.ReportSections" kann nicht gefunden werden, da es nicht vorhanden ist oder Sie keine Berechtigungen haben.

Es fällt mir nicht leicht, herauszufinden, was hier falsch ist. Jeder Einblick wäre enorm hilfreich.

90
Chev

Keine Ursache. Ich machte diesen Weg komplizierter, als es wirklich sein musste.

Das war alles was ich brauchte. Die Umbenennungsmethoden generieren nur einen Aufruf der gespeicherten Systemprozedur sp_rename , und ich denke, das hat alles erledigt, einschließlich der Fremdschlüssel mit dem neuen Spaltennamen.

public override void Up()
{
    RenameTable("ReportSections", "ReportPages");
    RenameTable("ReportSectionGroups", "ReportSections");
    RenameColumn("ReportPages", "Group_Id", "Section_Id");
}

public override void Down()
{
    RenameColumn("ReportPages", "Section_Id", "Group_Id");
    RenameTable("ReportSections", "ReportSectionGroups");
    RenameTable("ReportPages", "ReportSections");
}
125
Chev

Wenn Sie den erforderlichen Code in der Migrationsklasse nicht manuell schreiben/ändern möchten, können Sie einen zweistufigen Ansatz verfolgen, bei dem der erforderliche RenameColumn -Code automatisch erstellt wird:

Erster Schritt Verwenden Sie ColumnAttribute, um den neuen Spaltennamen einzuführen, und fügen Sie dann die Migration hinzu (z. B. Add-Migration ColumnChanged)

public class ReportPages
{
    [Column("Section_Id")]                 //Section_Id
    public int Group_Id{get;set}
}

Schritt 2 Ändern des Eigenschaftsnamens und erneutes Anwenden auf dieselbe Migration (z. B. Add-Migration ColumnChanged -force) in der Package Manager-Konsole

public class ReportPages
{
    [Column("Section_Id")]                 //Section_Id
    public int Section_Id{get;set}
}

Wenn Sie sich die Migrationsklasse ansehen, sehen Sie, dass der automatisch generierte Code RenameColumn ist.

32

Um die Antwort von Hossein Narimani Rad ein wenig zu erweitern, können Sie sowohl eine Tabelle als auch Spalten mit System.ComponentModel.DataAnnotations.Schema.TableAttribute bzw. System.ComponentModel.DataAnnotations.Schema.ColumnAttribute umbenennen.

Dies hat einige Vorteile:

  1. Dadurch werden nicht nur die Namensmigrationen automatisch erstellt, sondern auch
  2. außerdem werden Fremdschlüssel auf köstliche Weise gelöscht und anhand der neuen Tabellen- und Spaltennamen neu erstellt, wobei die Eigennamen der Fremdschlüssel und Konstanten angegeben werden.
  3. All dies, ohne Tabellendaten zu verlieren

Beispiel: [Table("Staffs")] hinzufügen:

[Table("Staffs")]
public class AccountUser
{
    public long Id { get; set; }

    public long AccountId { get; set; }

    public string ApplicationUserId { get; set; }

    public virtual Account Account { get; set; }

    public virtual ApplicationUser User { get; set; }
}

Erzeugt die Migration:

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropForeignKey(
            name: "FK_AccountUsers_Accounts_AccountId",
            table: "AccountUsers");

        migrationBuilder.DropForeignKey(
            name: "FK_AccountUsers_AspNetUsers_ApplicationUserId",
            table: "AccountUsers");

        migrationBuilder.DropPrimaryKey(
            name: "PK_AccountUsers",
            table: "AccountUsers");

        migrationBuilder.RenameTable(
            name: "AccountUsers",
            newName: "Staffs");

        migrationBuilder.RenameIndex(
            name: "IX_AccountUsers_ApplicationUserId",
            table: "Staffs",
            newName: "IX_Staffs_ApplicationUserId");

        migrationBuilder.RenameIndex(
            name: "IX_AccountUsers_AccountId",
            table: "Staffs",
            newName: "IX_Staffs_AccountId");

        migrationBuilder.AddPrimaryKey(
            name: "PK_Staffs",
            table: "Staffs",
            column: "Id");

        migrationBuilder.AddForeignKey(
            name: "FK_Staffs_Accounts_AccountId",
            table: "Staffs",
            column: "AccountId",
            principalTable: "Accounts",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);

        migrationBuilder.AddForeignKey(
            name: "FK_Staffs_AspNetUsers_ApplicationUserId",
            table: "Staffs",
            column: "ApplicationUserId",
            principalTable: "AspNetUsers",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropForeignKey(
            name: "FK_Staffs_Accounts_AccountId",
            table: "Staffs");

        migrationBuilder.DropForeignKey(
            name: "FK_Staffs_AspNetUsers_ApplicationUserId",
            table: "Staffs");

        migrationBuilder.DropPrimaryKey(
            name: "PK_Staffs",
            table: "Staffs");

        migrationBuilder.RenameTable(
            name: "Staffs",
            newName: "AccountUsers");

        migrationBuilder.RenameIndex(
            name: "IX_Staffs_ApplicationUserId",
            table: "AccountUsers",
            newName: "IX_AccountUsers_ApplicationUserId");

        migrationBuilder.RenameIndex(
            name: "IX_Staffs_AccountId",
            table: "AccountUsers",
            newName: "IX_AccountUsers_AccountId");

        migrationBuilder.AddPrimaryKey(
            name: "PK_AccountUsers",
            table: "AccountUsers",
            column: "Id");

        migrationBuilder.AddForeignKey(
            name: "FK_AccountUsers_Accounts_AccountId",
            table: "AccountUsers",
            column: "AccountId",
            principalTable: "Accounts",
            principalColumn: "Id",
            onDelete: ReferentialAction.Cascade);

        migrationBuilder.AddForeignKey(
            name: "FK_AccountUsers_AspNetUsers_ApplicationUserId",
            table: "AccountUsers",
            column: "ApplicationUserId",
            principalTable: "AspNetUsers",
            principalColumn: "Id",
            onDelete: ReferentialAction.Restrict);
    }
12
Etienne Morin

In EF Core (2.0) verwende ich die folgenden Anweisungen, um Tabellen und Spalten umzubenennen:

Wie zum Umbenennen von Tabellen:

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.RenameTable(name: "OldTableName", schema: "dbo", newName: "NewTableName", newSchema: "dbo");
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.RenameTable(name: "NewTableName", schema: "dbo", newName: "OldTableName", newSchema: "dbo");
    }

Wie zum Umbenennen von Spalten:

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.RenameColumn(name: "OldColumnName", table: "TableName", newName: "NewColumnName", schema: "dbo");
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.RenameColumn(name: "NewColumnName", table: "TableName", newName: "OldColumnName", schema: "dbo");
    }
6
mirind4

Ich habe gerade das gleiche in EF6 versucht (Code erste Entität umbenennen). Ich habe die Klasse einfach umbenannt und eine Migration mit der Package Manager-Konsole und voila hinzugefügt. Eine Migration mit RenameTable (...) wurde automatisch für mich generiert. Ich muss zugeben, dass ich dafür gesorgt habe, dass die einzige Änderung an der Entität darin bestand, sie umzubenennen, also keine neuen Spalten oder umbenannten Spalten, sodass ich nicht sicher sein kann, ob dies eine EF6-Sache ist oder nur, dass EF (immer) in der Lage war, solche einfachen Migrationen zu erkennen.

2
naskew

Tabellennamen und Spaltennamen können im Rahmen der Zuordnung von DbContext angegeben werden. Dann müssen Sie dies bei Migrationen nicht tun.

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Restaurant>()
            .HasMany(p => p.Cuisines)
            .WithMany(r => r.Restaurants)
            .Map(mc =>
            {
                mc.MapLeftKey("RestaurantId");
                mc.MapRightKey("CuisineId");
                mc.ToTable("RestaurantCuisines");
            });
     }
}
0
Martin Staufcik