Entity Framework Core でデータを削除せずに外部キーの名前を変更する 質問する

Entity Framework Core でデータを削除せずに外部キーの名前を変更する 質問する

モデルクラスが 2 つあります。

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

Surveyを に変更したいStudentSurveyので、 になりますStudentSurveyId。それに応じてモデル内のクラス名とプロパティを更新し、移行を追加します。

しかし、私はこう思います:

ALTER TABLE ステートメントは FOREIGN KEY 制約 "FK_User_Surveys_SurveyId" と競合しています。競合はデータベース "AppName"、テーブル "dbo.Survey"、列 'SurveyId' で発生しました。

データを削除しようとしているのだと思いますが、列にデータが必要なので (null にできません)、このエラーが表示されます。しかし、データを削除したくはありません。名前を変更するにはどうすればいいでしょうか?

ベストアンサー1

EF Core は、エンティティ クラスの名前変更を、古いエンティティの削除と新しいエンティティの追加として扱うため、元のテーブルを削除して新しいテーブルを作成するための移行を生成します。

回避策には次の手順が必要です。

(1) エンティティの名前を変更する前に、Fluent API またはデータ注釈を使用して、テーブルと PK 列の名前を変更しますToTableHasColumnNameエンティティを参照する 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; }
}

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

(3)アノテーション/ Fluent 構成を削除し、実際のクラス/プロパティの名前変更を実行します。

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

対応するものDbSetがあれば名前を変更します:

public DbSet<StudentSurvey> StudentSurveys { get; set; }

これで完了です。

新しい移行を追加することでそれを確認できます。空のメソッドUpDownメソッドが含まれます。

おすすめ記事