#c# #entity-framework-core #cascading-deletes
Вопрос:
У меня есть эти сущности Course
Student
и промежуточная таблица CourseStudent
.
public class Course { public decimal Id { get; set; } public decimal IdState { get; set; } public decimal IdCity { get; set; } public string Name { get; set; } public Listlt;CourseStudentgt; CourseStudents { get; set; } = new Listlt;CourseStudentgt;(); } public class Student { public decimal Id { get; set; } public decimal IdState { get; set; } public decimal IdCity { get; set; } public string Name { get; set; } public Listlt;CourseStudentgt; CourseStudents { get; set; } = new Listlt;CourseStudentgt;(); } public class CourseStudent { public decimal Id { get; set; } public decimal IdState { get; set; } public decimal IdCity { get; set; } public decimal IdCourse { get; set; } public decimal IdStudent { get; set; } public Course Course { get; set; } public Student Student { get; set; } }
Мои файлы конфигурации:
public class CourseStudentConfiguration : IEntityTypeConfigurationlt;CourseStudentgt; { public void Configure(EntityTypeBuilderlt;CourseStudentgt; builder) { builder.ToTable("Courses_Students"); builder.Property(x =gt; x.IdState).HasColumnType("numeric(18,0)").IsRequired(); builder.Property(x =gt; x.IdCity).HasColumnType("numeric(18,0)").IsRequired(); builder.Property(x =gt; x.IdCourse).HasColumnType("numeric(18,0)").IsRequired(); builder.Property(x =gt; x.IdStudent).HasColumnType("numeric(18,0)").IsRequired(); builder .HasOne(x =gt; x.Course) .WithMany(x =gt; x.CourseStudents) .HasForeignKey(x =gt; x.IdCourse) .OnDelete(DeleteBehavior.Cascade); builder .HasOne(x =gt; x.Student) .WithMany(x =gt; x.CourseStudents) .HasForeignKey(x =gt; x.IdStudent) .OnDelete(DeleteBehavior.Cascade); } }
Как вы можете видеть, мои отношения находятся только в моей промежуточной таблице.
public class CourseConfiguration : IEntityTypeConfigurationlt;Coursegt; { public void Configure(EntityTypeBuilderlt;Coursegt; builder) { builder.ToTable("Courses"); builder.Property(x =gt; x.IdState).HasColumnType("numeric(18,0)").IsRequired(); builder.Property(x =gt; x.IdCity).HasColumnType("numeric(18,0)").IsRequired(); builder.Property(x =gt; x.Name).HasColumnType("varchar(64)").IsRequired(); } } public class StudentConfiguration : IEntityTypeConfigurationlt;Studentgt; { public void Configure(EntityTypeBuilderlt;Studentgt; builder) { builder.ToTable("Students"); builder.Property(x =gt; x.IdState).HasColumnType("numeric(18,0)").IsRequired(); builder.Property(x =gt; x.IdCity).HasColumnType("numeric(18,0)").IsRequired(); builder.Property(x =gt; x.Name).HasColumnType("varchar(64)").IsRequired(); } }
Когда я удалял некоторые Course
CourseStudent
, они были удалены, как и ожидалось, но Student
они не были удалены, и мне тоже нужно их Student
удалить.
Какие изменения мне нужно внести в CourseStudentConfiguration
(или StudentConfiguration
), чтобы Student
их тоже удалили, когда Course
они будут удалены.
Комментарии:
1. Лучший способ-удалить курс, как вы это делаете, а затем удалить студента в отдельном вызове.
Ответ №1:
Задайте себе вопрос, можно ли закодировать его с помощью обычного SQL, потому что, если это невозможно сделать таким образом, его также нельзя настроить в EF.
ON DELETE CASCADE
является свойством, установленным для отношения внешнего ключа
[ CONSTRAINT constraint_name ] { FOREIGN KEY ( column [ ,...n ] ) REFERENCES referenced_table_name [ ( ref_column [ ,...n ] ) ] [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] [ NOT FOR REPLICATION ] }
Вы установили два ON DELETE CASCADE
для CourseStudent
:
IdCourse REFERENCES Courses (Id) ON DELETE CASCADE
IdStudent REFERENECS Students (Id) ON DELETE CASCADE
Это означает, что курс будет удален, если будет удален Студент или Курс. В таблице учащихся не определена связь с внешним ключом, поэтому она не будет удалена — и это ожидаемое поведение. Вы бы также ожидали, что курс будет удален, если студент будет удален? Я так не думаю 🙂
Решение:
- Удаляйте объект Student в коде «вручную» каждый раз, когда вы удаляете CourseStudent. Эта логика может быть инкапсулирована в какой-либо репозиторий/сервис.
- Вы можете либо определить триггер базы данных
СОЗДАЙТЕ ТРИГГЕР sampleTrigger В CourseStudent ДЛЯ УДАЛЕНИЯ КАК УДАЛИТЬ ИЗ ученика, В КОТОРОМ УКАЗАН идентификатор (ВЫБЕРИТЕ удалено.IdStudent ИЗ удалено) ПЕРЕЙТИ