Reputation: 3496
I am using asp.net core 3 web api
and EF core 3
I have a one to many
relationship between 2 tables:
Task
and TaskType
Task
has one TaskType
TaskType
has many Tasks
Here are the 2 entities:
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; }
}
When I run the add-migration
command it generates this code
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");
}
Notice the line onDelete: ReferentialAction.Delete
which obviously is an error and should cascade the other way.
To fix this, I want to change it to ReferentialAction.NoAction
and add this code to my onModelCreating
in my context
modelBuilder.Entity<TaskType>()
.HasMany(c => c.Tasks)
.WithOne(e => e.TaskType)
.OnDelete(DeleteBehavior.Cascade);
Is this the correct way to add cascade delete for a one to many relationship? Should I be modifying the generated migration code or is there another way to tell EF not to cascade delete the TaskType
when I delete a Task
?
Edit:
The accepted answer helped me come up with ha solution. I should have been more specific, I needed the orphaned TaskType
records. So I set the TaskTypeID
FK to a nullable Guid
and in my OnDelete()
I set the option to ReferentialAction.SetNull
Upvotes: 0
Views: 1188
Reputation: 1187
The direction is correct.
If you were to delete a Task
by cascading from the delete of a TaskType
then you could quite possibly leave a lot of orphaned TaskType
records (assuming there was no referential integrity).
The entity TaskType
depends on the Task
entity, so the only valid scsenario for deleting a Task
is to delete all of the associated TaskType
records.
One common approach to getting around this is to use a soft delete.
Essentially add a property to the entity
public bool IsDeleted { get; set; }
and you can then know that an entity is deleted, but still maintain the correct references.
Upvotes: 3