在不丢弃数据的情况下重命名Entity Framework Core中的外键

egm*_*frs 5 c# sql-server entity-framework entity-framework-core ef-core-2.0

我有两个模型类:

public class Survey
{
    public int SurveyId { get; set; }
    public string Name { get; set; }
}

public class User
{
    public int UserId { get; set; }

    public int SurveyId { get; set; }
    public Survey Survey { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我要重命名SurveyStudentSurvey,所以就会产生StudentSurveyId.我相应地更新了模型中的类名和属性,并添加了一个迁移.

但是,我得到:

ALTER TABLE语句与FOREIGN KEY约束"FK_User_Surveys_SurveyId"冲突.冲突发生在数据库"AppName",表"dbo.Survey",列"SurveyId"中.

我认为它试图删除数据,因为它需要列中的数据(不能为空)我看到了这个错误.但我不想丢弃数据.我怎样才能重命名呢?

Iva*_*oev 14

EF Core将实体类重命名为删除旧实体并添加新实体,因此生成迁移以删除原始表并创建新表.

解决方法需要以下步骤:

(1)重命名实体之前,通过使用"重命名"的表和PK柱ToTableHasColumnName流利API或数据注释.对引用该实体的FK列也执行相同操作.

例如:

[Table("StudentSurveys")]
public class Survey
{
    [Column("StudentSurveyId")]
    public int SurveyId { get; set; }
    public string Name { get; set; }
}

public class User
{
    public int UserId { get; set; }
    [Column("StudentSurveyId")]
    public int SurveyId { get; set; }
    public Survey Survey { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

(2)添加新迁移.它将正确地重命名表,PK列,FK列和相关的约束:

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

    migrationBuilder.DropPrimaryKey(
        name: "PK_Surveys",
        table: "Surveys");

    migrationBuilder.RenameTable(
        name: "Surveys",
        newName: "StudentSurveys");

    migrationBuilder.RenameColumn(
        name: "SurveyId",
        table: "Users",
        newName: "StudentSurveyId");

    migrationBuilder.RenameIndex(
        name: "IX_Users_SurveyId",
        table: "Users",
        newName: "IX_Users_StudentSurveyId");

    migrationBuilder.RenameColumn(
        name: "SurveyId",
        table: "StudentSurveys",
        newName: "StudentSurveyId");

    migrationBuilder.AddPrimaryKey(
        name: "PK_StudentSurveys",
        table: "StudentSurveys",
        column: "StudentSurveyId");

    migrationBuilder.AddForeignKey(
        name: "FK_Users_StudentSurveys_StudentSurveyId",
        table: "Users",
        column: "StudentSurveyId",
        principalTable: "StudentSurveys",
        principalColumn: "StudentSurveyId",
        onDelete: ReferentialAction.Cascade);
}
Run Code Online (Sandbox Code Playgroud)

(3)删除注释/流畅配置并执行实际的类/属性重命名:

public class StudentSurvey
{
    public int StudentSurveyId { get; set; }
    public string Name { get; set; }
}

public class User
{
    public int SurveyUserId { get; set; }
    public int StudentSurveyId { get; set; }
    public StudentSurvey StudentSurvey { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

重命名相应的DbSetif if:

public DbSet<StudentSurvey> StudentSurveys { get; set; }
Run Code Online (Sandbox Code Playgroud)

你完成了

您可以通过添加新迁移来验证它 - 它将具有空UpDown方法.

  • 在 EF core 3 中:如果我不生成第二个(空)迁移,那么我仍然在 ModelSnapshot 中: b.Property&lt;string&gt;("Old") .HasColumnName("New") (3认同)
  • 好。至少这是一个很好的起点:)在我的测试中,我没有重命名FK列。并且假设`DbSet`重命名是“重命名”操作的一部分。无论如何,答案现在已更新,我错过了什么吗? (2认同)