我有两个模型类:
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",table" dbo.Survey",column' SurveyId'。
我认为它试图删除数据,因为它需要列中的数据(不能为空)我看到了这个错误。但我不想丢弃数据。我怎样才能重命名呢?
答案 0 :(得分:10)
EF Core将实体类重命名为删除旧实体并添加新实体,因此生成迁移以删除原始表并创建新表。
解决方法需要执行以下步骤:
(1)在重命名实体之前,使用HasColumnName
和[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; }
}
流畅的API或数据注释“重命名”表和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);
}
(2)添加新迁移。它将正确地重命名表,PK列,FK列和相关约束:
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; }
}
(3)删除注释/流畅配置并执行实际的类/属性重命名:
DbSet
重命名相应的public DbSet<StudentSurvey> StudentSurveys { get; set; }
(如果有):
Up
你完成了。
您可以通过添加新的迁移来验证它 - 它将采用空的Down
和In [120]: df[df.days_old > 3]['fruit'].value_counts()
Out[120]:
apple 2
orange 1
Name: fruit, dtype: int64
方法。
答案 1 :(得分:1)
documentation 建议使用 MigrationBuilder.RenameColumn()
。还有 RenameIndex()
、RenameTable()
和存储过程“sp_rename”(在 SQL Server 中)用于重命名外键。例如:
migrationBuilder.Sql($"EXEC sp_rename 'dbo.{oldName}', '{newName}'");
使用 SQL Server Management Studio 中的数据库脚本工具(rt-click DB | Tasks | Generate Scripts...)生成架构脚本,有和没有 EF 迁移自定义< /strong>,可以比较。然后你就会知道 EF 命名被保留了。
编辑:添加了“EXEC ...”以支持生成独立的 T-SQL 脚本