Entity framework 6, каскадне видалення даних
За замовчуванням Code-First включає каскадне видалення для зовнішніх ключів, які не підтримують значення NULL, використовуючи відповідний SQL-код при створенні таблиці. У попередній статті ми описали, як вказати Code-First на те, що зовнішній ключ повинен обов'язково використовуватися (тобто підтримувати обмеження NOT NULL). Давайте згадаємо, як це зробити:
Можна явно вказати властивість зовнішнього ключа, тоді Code-First за замовчуванням використовує для нього значення NOT NULL в базі даних. У прикладах ми використовували зовнішні ключі CustomerId і UserId.
Якщо зовнішній ключ не вказано в класі моделі, тоді Code-First автоматично генерує його, дозволяючи використовувати NULL. Щоб це змінити, можна використовувати атрибут Required до навігаційного властивості моделі.
Давайте розглянемо приклад використання каскадного видалення на прикладі нашого тестового проекту ASP.NET. Для цього додамо нову веб-форму CascadeDelete.aspx і додамо наступний код:
У цій формі використовуються дві кнопки для видалення і збереження даних. У коді обробника Save_Click відбувається створення довільного об'єкта Customer з трьома зв'язаними об'єктами Order, після чого ці дані вставляються в базу. У коді обробника Delete_Click ми спочатку витягаємо дані потрібного замовника з бази даних, а потім видаляємо його. Зверніть увагу, що тут використовується "жадібне завантаження" (eager loading). тому ми викликаємо метод Include (). Це означає, що крім даних покупця, будуть вилучені всі дані пов'язаних з ним замовлень. Фактично каскадне видалення в даному випадку не потрібно, тому що ми вже витягли все пов'язані замовлення.
Модель даних на поточний момент виглядає наступним чином:

Натисніть на кнопку "Видалити", щоб переконатися, що дані покупця і пов'язані з ним замовлення видаляються коректно. При цьому Entity Framework відправить чотири запиту DELETE базі даних (три для кожного замовлення і один для покупця). Давайте тепер відключимо використання жадібної завантаження і явно використовуємо каскадне видалення. Нижче показаний змінений код обробника Delete_Click:
Тут ми видалили виклик методу Include () і тепер Code-First не відомо про пов'язаних з покупцем замовлень. На відміну від попереднього прикладу, тут Entity Framework відправить один запит DELETE для видалення покупця. При виконанні цього запиту спрацює засіб каскадного видалення і SQL Server знайде пов'язані замовлення, видалить спочатку їх, а вже потім видалить покупця.
Відключення каскадного видалення даних
Важливо пам'ятати, що при відключенні каскадного видалення в вашому додатку можуть виникати помилки, якщо ви не подбаєте про видаляння пов'язаних даних перед видаленням, як ми це робили в першому прикладі з використанням "жадібної завантаження".
Відключити або включити каскадне видалення в Fluent API дозволяє метод WillCascadeOnDelete (). якому передається логічний параметр. Використання цього методу показано в прикладі нижче:
Якщо ви запустите додаток і спробуєте видалити дані, використовуючи другий приклад обробника Delete_Click, то виникне виняток, показане на малюнку нижче:

Як вже описувалося раніше, при видаленні даних з батьківської таблиці, необхідно подбати про видалення даних з похідною таблиці. Ми забули витягти дані пов'язаних замовлень з таблиці Orders і тому SQL Server повернув помилку при спробі видалення даних тільки покупця. Якщо ви тепер включите "жадібну завантаження" за допомогою методу Include () в обробнику Delete_Click, то ця помилка зникне, але виникне нова - як описувалося вище, в цьому випадку Code-First відправить чотири запиту на видалення та при видаленні першого замовлення Code-First встановить для властивості Order.Customer значення NULL, а тому наша модель містить зовнішній ключ, який не може мати значення NULL виникне помилка.
Також відключення каскадного видалення потрібно для таблиць, які визначають кілька відносин між собою. Деякі бази даних (в тому числі SQL Server) не підтримують кілька відносин, які визначають каскадне видалення, що визначене на одній таблиці.