source

엔티티 프레임워크 마이그레이션의 테이블 및 열 이름 변경

lovecheck 2023. 4. 7. 21:32
반응형

엔티티 프레임워크 마이그레이션의 테이블 및 열 이름 변경

몇 개의 엔티티와 엔티티의 탐색 속성의 이름을 변경하고 EF 5에서 새 마이그레이션을 생성했습니다. EF 마이그레이션의 이름 변경과 마찬가지로 기본적으로는 개체를 삭제하고 다시 만듭니다.이것은 제가 원했던 것이 아니기 때문에 이행 파일을 처음부터 작성해야 했습니다.

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

이름만 바꾸려고 해dbo.ReportSections로.dbo.ReportPages그리고 나서.dbo.ReportSectionGroups로.dbo.ReportSections그러면 다음에서 외부 키 열의 이름을 변경해야 합니다.dbo.ReportPages부터Group_Id로.Section_Id.

테이블을 링크하는 외부 키와 인덱스를 삭제하고 테이블과 외부 키 열의 이름을 변경한 후 다시 인덱스와 외부 키를 추가합니다.정상적으로 동작할 것으로 생각했지만 SQL 에러가 발생하고 있습니다.

Msg 15248, Level 11, State 1, Procedure sp_rename, Line 215 파라미터 @objname이 애매하거나 클레임된 @objtype(COLUMN)이 잘못되었습니다.Msg 4902, 레벨 16, 상태 1, 10 행 "dbo" 객체를 찾을 수 없습니다.ReportSections"가 존재하지 않거나 권한이 없기 때문입니다.

여기 뭐가 문제인지 알아내기가 쉽지 않아요.어떤 통찰이라도 엄청난 도움이 될 것이다.

됐어.난 이 방법을 실제보다 더 복잡하게 만들고 있었어.

이게 내가 필요한 전부였다.rename 메서드는 sp_rename 시스템 스토어드 프로시저에 대한 호출을 생성하기만 하면 됩니다.또, 새로운 컬럼명의 외부 키를 포함한 모든 것을 처리할 수 있다고 생각합니다.

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

이행 클래스에서 필요한 코드를 수동으로 작성/변경하고 싶지 않은 경우 2단계 접근법에 따라 자동으로 다음 작업을 수행할 수 있습니다.RenameColumn필요한 코드:

순서 1 의 사용ColumnAttribute새 열 이름을 소개하고 추가 이름을 추가합니다(예:Add-Migration ColumnChanged)

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

2단계: 속성 이름을 변경하고 동일한 마이그레이션에 다시 적용합니다(예:Add-Migration ColumnChanged -forcePackage Manager Console ) 。

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

이행 클래스를 보면 자동으로 생성되는 코드는 다음과 같습니다.RenameColumn.

EF Core에서는 다음 문을 사용하여 테이블과 열의 이름을 변경합니다.

테이블 이름 변경의 경우:

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

컬럼 이름 변경의 경우:

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

Hossein Narimani Rad의 답변에 대한 비트를 확장하려면 System을 사용하여 테이블과 컬럼의 이름을 변경할 수 있습니다.컴포넌트 모델데이터 주석Schema.TableAttribute 및 System.컴포넌트 모델데이터 주석각각 Schema.ColumnAttribute.

여기에는 몇 가지 이점이 있습니다.

  1. 그러면 마이그레이션이라는 이름이 자동으로 생성될 뿐만 아니라
  2. 또한 외부 키를 삭제하고 새 테이블 및 열 이름에 대해 다시 생성하여 외부 키를 지정하고 적절한 이름을 유지합니다.
  3. 테이블 데이터를 잃지 않고 이 모든 것

를 들어, 「」, 「」를 추가합니다.[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; }
}

이행을 생성합니다.

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

ef core에서는 마이그레이션 추가 후 생성된 마이그레이션을 변경할 수 있습니다.그런 다음 데이터베이스 업데이트를 수행합니다.샘플은 다음과 같습니다.

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.RenameColumn(name: "Type", table: "Users", newName: "Discriminator", schema: "dbo");
}

protected override void Down(MigrationBuilder migrationBuilder)
{            
    migrationBuilder.RenameColumn(name: "Discriminator", table: "Users", newName: "Type", schema: "dbo");
}

Core EF Core ™의 경우migrationBuilder.RenameColumn보통 정상적으로 동작하지만 인덱스를 처리해야 하는 경우도 있습니다.

migrationBuilder.RenameColumn(name: "Identifier", table: "Questions", newName: "ChangedIdentifier", schema: "dbo");

데이터베이스 업데이트 시 오류 메시지 예:

마이크로소프트(MS.Data.SqlClient.Sql Exception (0x80131904) :'IX_Questions_Identifier' 색인은 'Identifier' 열에 종속됩니다.

'IX_Questions_Identifier' 색인은 'Identifier' 열에 종속됩니다.

하나 이상의 개체가 이 열에 액세스하기 때문에 RENAME COLUMN ID에 실패했습니다.

이 경우 다음과 같이 이름을 변경해야 합니다.

migrationBuilder.DropIndex(
    name: "IX_Questions_Identifier",
    table: "Questions");

migrationBuilder.RenameColumn(name: "Identifier", table: "Questions", newName: "ChangedIdentifier", schema: "dbo");

migrationBuilder.CreateIndex(
    name: "IX_Questions_ChangedIdentifier",
    table: "Questions",
    column: "ChangedIdentifier",
    unique: true,
    filter: "[ChangedIdentifier] IS NOT NULL");

EF6(코드 퍼스트 엔티티 이름 변경)에서도 같은 시도를 했습니다.클래스 이름을 변경하고 패키지 매니저 콘솔과 voila를 사용한 마이그레이션을 추가하면 RenameTable(...)을 사용한 마이그레이션이 자동으로 생성되었습니다.엔티티에 대한 유일한 변경 사항은 새 열이나 열 이름이 변경되지 않도록 이름을 변경하는 것이었으므로 이것이 EF6인지 아니면 EF가 이러한 단순한 마이그레이션을 항상 감지할 수 있었는지 확신할 수 없습니다.

및 열 할 수 .DbContext이행에서는 이 작업을 수행할 필요가 없습니다.

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

Hossein Narimani Rad의 대답은 정말 멋지고 직설적이다.하지만 EF 코어에서는 작동하지 않습니다.dotnet ef migration add를 가지고 있지 않다.--force★★★★★★ 。

이렇게 해야 돼요.

- add 1 - 가가[Column("NewColumnName")]

- - 이행 작성2"dotnet ef migration add RenameSomeColumn

의 모든 하세요. - 의 모든 코드를 복사하세요.RenameSomeColumn.cs

- 4 - 이행 삭제dotnet ef migrations remove

- 5 - 제거[Column("NewColumnName")][ ]의을 [Resignment]으로 합니다.NewColumnName

- 6 - 하다dotnet ef migration add RenameSomeColumn

- 에서 새로운7로 된 모든 - "모든 코드 "RenameSomeColumn.cs

언급URL : https://stackoverflow.com/questions/13296996/entity-framework-migrations-renaming-tables-and-columns

반응형