我正在使用asp.net core 3 web api
和EF core 3
,我在两个表之间有一个one to many
关系:
Task
和TaskType
Task
有一个TaskType
TaskType
有很多Tasks
这是2个实体:
public class TaskType
{
public TaskType() {
Tasks = new HashSet<Task>();
}
[Key]
public Guid TaskTypeID { get;set; }
...
public ICollection<Task> Tasks { get; set; }
}
public class Task
{
public Task() {
}
[Key]
public Guid TaskID {get;set;}
...
public Guid TaskTypeID { get; set; }
[ForeignKey("TaskTypeID")]
public TaskType TaskType { get; set; }
}
当我运行add-migration
命令时,它将生成此代码
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "TaskTypeID",
table: "Task",
nullable: false,
defaultValue: new Guid("00000000-0000-0000-0000-000000000000"));
migrationBuilder.CreateIndex(
name: "IX_Task_TaskTypeID",
table: "Task",
column: "TaskTypeID");
migrationBuilder.AddForeignKey(
name: "FK_Task_TaskType_TaskTypeID",
table: "Task",
column: "TaskTypeID",
principalTable: "TaskType",
principalColumn: "TaskTypeID",
onDelete: ReferentialAction.Delete);// I want to change this to ReferentialAction.NoAction
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Task_TaskType_TaskTypeID",
table: "Task");
migrationBuilder.DropIndex(
name: "IX_Task_TaskTypeID",
table: "Task");
migrationBuilder.DropColumn(
name: "TaskTypeID",
table: "Task");
}
请注意,onDelete: ReferentialAction.Delete
行显然是错误的,应该以另一种方式级联。
要解决此问题,我想将其更改为ReferentialAction.NoAction
并在上下文中将此代码添加到我的onModelCreating
modelBuilder.Entity<TaskType>()
.HasMany(c => c.Tasks)
.WithOne(e => e.TaskType)
.OnDelete(DeleteBehavior.Cascade);
这是为一对多关系添加级联删除的正确方法吗?我应该修改生成的迁移代码,还是有另一种方法告诉我在删除TaskType
时不要级联删除Task
?
编辑:
接受的答案帮助我提出了解决方案。我应该更具体一些,我需要孤立的TaskType
记录。因此,我将TaskTypeID
FK设置为可为空的Guid
,并在我的OnDelete()
中将选项设置为ReferentialAction.SetNull
答案 0 :(得分:3)
方向正确。
如果要通过从删除const f = new Frame("z");
f.content = null; // error, can't assign to read only
function acceptFrame(f: Frame) {
f.content = null; // error here too
}
的级联来删除Task
,则很可能会留下很多孤立的TaskType
记录(假设没有参照完整性)
实体TaskType
依赖于TaskType
实体,因此删除Task
的唯一有效方案是删除所有关联的Task
记录。
解决此问题的一种常用方法是使用 soft 删除。
本质上为实体添加属性
TaskType
,您便可以知道已删除实体,但仍保留正确的引用。