Frage Entity Framework Migrations, die Tabellen und Spalten umbenennen


Ich habe ein paar Entitäten und deren Navigationseigenschaften umbenannt und in EF 5 eine neue Migration generiert. Wie bei Umbenennungen in EF-Migrationen üblich, wurden standardmäßig Objekte gelöscht und neu erstellt. 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 umzubenennen dbo.ReportSections zu dbo.ReportPages und dann dbo.ReportSectionGroups zu dbo.ReportSections. Dann muss ich die Fremdschlüsselspalte auf umbenennen dbo.ReportPages von Group_Id zu Section_Id.

Ich lasse die Fremdschlüssel und Indizes fallen, die die Tabellen miteinander verbinden, dann benenne ich die Tabellen und die Fremdschlüsselspalte um, dann füge ich die Indizes und Fremdschlüssel wieder hinzu. Ich nahm an, dass dies funktionieren würde, aber ich bekomme einen SQL-Fehler.

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

Es fällt mir nicht leicht, herauszufinden, was hier falsch ist. Jede Einsicht wäre ungeheuer hilfreich.


76
2017-11-08 20:12


Ursprung


Antworten:


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

Das war alles was ich brauchte. Die Umbenennungsmethoden erzeugen nur einen Aufruf an die sp_rename System gespeicherte Prozedur und ich denke, das hat sich um alles gekümmert, 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");
}

108
2017-11-08 20:27



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

Schritt eins Benutze die ColumnAttribute um den neuen Spaltennamen einzuführen und dann die Migration hinzuzufügen (z.B. Add-Migration ColumnChanged)

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

Schritt zwei Ändern Sie den Eigenschaftsnamen und gelten Sie erneut für dieselbe Migration (z. Add-Migration ColumnChanged) 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 den automatisch generierten Code RenameColumn.


19
2017-07-23 07:40



Um ein wenig die Antwort von Hossein Narimani Rad 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 ein paar Vorteile:

  1. Dies wird nicht nur automatisch den Namen Migrationen erstellen, sondern
  2. Es löscht auch wunderbar alle Fremdschlüssel und erstellt sie gegen die neuen Tabellen- und Spaltennamen neu, wobei die Fremdschlüssel angegeben werden und die Eigennamen konstant bleiben.
  3. All dies ohne Verlust von Tabellendaten

Zum Beispiel, Hinzufügen [Table("Staffs")]:

[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; }
}

Wird die Migration generieren:

    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);
    }

6
2018-05-31 02:16



Ich habe das gleiche in EF6 versucht (code first entity rename). Ich habe die Klasse einfach umbenannt und eine Migration über die Paketmanager-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 Entity darin umbenannt wurde, also keine neuen Spalten oder umbenannten Spalten, so dass ich nicht sicher sein kann, ob dies eine EF6-Sache ist oder EF einfach (immer) solche einfachen Migrationen erkennen kann.


2
2017-12-21 11:42



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

Wie für das 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: "Orders", newName: "OldColumnName", schema: "dbo");
    }

2
2018-06-16 08:16



Tabellennamen und Spaltennamen können als Teil des Mappings von angegeben werden DbContext. Dann ist es nicht notwendig, dies bei Migrationen zu 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
2018-05-07 08:26