0

У меня есть followed the docs для настройки отношений «многие ко многим», используя таблицу соединений, которая отображается как сущность.Как моделировать удаление в отношениях EF Core со многими?

Но в документах не упоминается, что я должен сделать для удаления.

Так, например, у Student много учителей, а у Teacher много учеников. Объект объединения/таблица - StudentTeacher.

Джойн стол/организация:

public class StudentTeacher { 
    public int StudentId { get; set; } 
    public Student Student { get; set; } 
    public int TeacherId { get; set; } 
    public Teacher Teacher { get; set; } 
} 

конфиг для присоединения таблицы/лица:

modelBuilder.Entity<StudentTeacher>() 
    .HasOne(b => b.Teacher) 
    .WithMany(b => b.StudentTeachers) 
    .HasForeignKey(b => b.TeacherId) 
    .IsRequired() 
    .OnDelete(/* ... what goes here? ...*/); 

modelBuilder.Entity<StudentTeacher>() 
    .HasOne(b => b.Student) 
    .WithMany(b => b.StudentTeachers) 
    .HasForeignKey(b => b.StudentId) 
    .IsRequired() 
    .OnDelete(/* ... what goes here? ...*/); 

Что я использую в OnDelete()? И почему?

ответ

0

Это кажется запутанным сначала смоделировать таблицу присоединиться, потому что < = EF6 не нужно. Но на самом деле это просто.

При удалении объекта Teacher необходимо удалить его отношения ко всем объектам Student. При удалении объекта Student вам необходимо удалить его отношения ко всем объектам Teacher.

Таким образом, объекты объединения должны быть всегда CASCADE удалены.

+0

Да, вы правы. Это то, что я сделал большинство моих таблиц отношений. Как насчет того, что я не хочу удалять отношения на стороне db? Мне нужно регистрировать или архивировать некоторые важные отношения. В этом примере ученика учителя это не обязательно, но у меня такая ситуация. Что бы вы сделали или предложили что-нибудь? @grokky – kizilsu

+0

@kizilsu Я считаю, что проще всего установить триггер на db и создать журнал аудита таким образом. Или, сопоставьте его в EF и создайте запись каждый раз, когда вы удаляете. – grokky

1

.OnDelete(/* ... what goes here? ...*/);

Вы должны указать здесь, что DB должны делать с детьми записей (в StudentTeacher), когда родительские записи (в Student или Teacher) удаляется: удалить слишком (Cascade) или запретить и бросать ошибку (Restrict) если соответствующая детская запись существует. С Restrict вы должны вручную удалить дочерние записи перед удалением родительского.

Но только вы можете решить, какое действие должно применяться для каждой связи - это ваше приложение, мы не знаем всех требований к нему.

Важно: с Cascade, удаление, скажем, Teacher будет влиять (удаление) только записи в StudentTeacher (с соответствующими TeacherId), но Students будет сохранять в неприкосновенности.

Важно 2: В MS SQL Server (вы не писали, что DB двигатель вы используете), вы можете установить только один в Cascade (другие должны быть Restrict), или вы получите сообщение об ошибке при применении миграции (Вводя FOREIGN KEY ограничение _some_name_ на столе _some_table_ может вызвать циклов или несколько путей каскадные.)

+0

Я уже знаю разницу между режимами удаления, но это особый случай, потому что это для таблицы соединений. В отличие от grokky

+1

Это как раз одна из моих проблем, я должен использовать каскад или нет?Я сделал каскад, но операция каскадного удаления работает на стороне db, и если нет триггера, вы не получите назад свои записи. Таким образом, я делал процесс удаления, когда пользователь обновлял таблицу регистрации, как удаление учителя студенту или наоборот. Таким образом, я могу отслеживать операции и сохранять записи. Может быть, вы тоже можете это сделать @grokky – kizilsu

+0

Ответ @kizilsu Dmitry правильный и дает хороший исходный код проблемы. Но чтобы решить, какой режим удаления использовать, см. Также мой ответ. – grokky