cascade = {“remove”} VS orphanRemoval = true VS ondelete = "КАСКАД


93

Я намагався зібрати небагато інформації про такі способи автоматичного видалення дочірньої сутності при видаленні батьківської сутності. Здається, найпоширенішим способом є використання однієї з цих трьох анотацій: cascade = {"remove"} АБО orphanRemoval = true АБО ondelete = "CASCADE" .

Я трохи заплутаний щодо третього: ondelete = "КАСКАД" , оскільки пояснення в офіційній документації доктрини щодо цього є дуже мізерними), і я був би дуже радий, якби хтось міг підтвердити мені наступну інформацію, яку я зібрав і зрозумів із моїх досліджень щодо мережа та досвід ...

ЩО ЦЕ РОБИТЬ

cascade = {"remove"}
==> сутність на зворотному боці видаляється, коли сутність, що володіє стороною, є. Навіть якщо ви перебуваєте в багатьох сім'ях з іншими сторонами, що володіють.
- повинен використовуватися для збору (так у відносинах OneToMany або ManyToMany)
- реалізація в ORM

orphanRemoval = true
==> сутність на зворотному боці видаляється, коли сутність, що володіє, є І І вона більше не підключена до жодної іншої сторони, що володіє. (посилання на доктрину official_doc - реалізація в ORM
- може використовуватися з OneToOne, OnetoMany або ManyToMany

onDelete = "CASCADE"
==> це додасть On Delete Cascade до стовпця зовнішнього ключа в базі даних
- Ця стратегія трохи складна для правильного вибору, але може бути дуже потужною та швидкою. (посилання на доктрину official_doc ... але не читав більше пояснень)
- ORM повинен виконувати менше роботи (порівняно з двома попередніми способами виконання), а отже, повинен мати кращу продуктивність.

інша інформація
- усі ці 3 способи здійснення реалізовані на двонаправлених сутностях відносин ( право ??? )
- за допомогою cascade = {"remove"} повністю обходить будь-який зовнішній ключ onDelete = CASCADE. (посилання doctrine_official_doc )

ПРИКЛАД, ЯК ВИКОРИСТОВУВАТИ ЦЕ В КОДІ

  • orphanRemoval і cascade = {"remove"} визначені в інверсованому класі сутності.
  • ondelete = "КАСКАД" визначено в сутності власника
  • Ви також можете просто написати @ORM \ JoinColumn (onDelete = "CASCADE") і дозволити доктрині обробляти імена стовпців

каскад = {"видалити"}

/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", cascade={"remove"})
*/
protected $Phonenumbers

orphanRemoval = true

/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", orphanRemoval=true)
*/
protected $Phonenumbers

onDelete = "КАСКАД"

/** 
* @ManyToOne(targetEntity="Contact", inversedBy="phonenumbers")
* @JoinColumn(name="contact_id", referencedColumnName="contact_id", onDelete="CASCADE")
*/ 
protected $contact; 

1
він має гарне пояснення stackoverflow.com/questions/25515007 / ...
Gregsparrow

Відповіді:


61

onDelete="CASCADE"управляється самою базою даних. cascade={"remove"}управляється доктриною.

onDelete="CASCADE"швидше, оскільки операції виконуються на рівні бази даних, а не доктриною. Видалення виконується сервером бази даних, а не Doctrine. За допомогою cascade={"remove"}доктрини має керувати самою суттю і буде проводити додаткові перевірки, щоб перевірити, чи не має вона інших власників. Коли жодного іншого не існує, він буде видалений. Але це створює накладні витрати.


каскад = {"видалити"}

  • сутність на зворотній стороні видаляється, коли сутність, що володіє стороною, є. Навіть якщо ви перебуваєте в багатьох сім'ях з іншими сторонами, що володіють. Ні, якщо організація належить чомусь іншому. Він не буде видалений.
  • слід використовувати для колекціонування (так у відносинах OneToMany або ManyToMany)
  • реалізація в ORM

orphanRemoval = "true"

  • сутність на зворотному боці видаляється, коли суб'єктом сторони, що володіє, є І І вона більше не підключена до жодної іншої сторони, що володіє. Не зовсім так, це змушує доктрину поводитись так, ніби вона не належить іншому суб’єкту, і, таким чином, видалити її.
  • реалізація в ORM
  • можна використовувати з OneToOne, OnetoMany або ManyToMany

onDelete = "КАСКАД"

  • це додасть On Delete Cascade до стовпця зовнішнього ключа В БАЗІ ДАНИХ
  • Ця стратегія трохи складна, щоб отримати правильне рішення, але вона може бути дуже потужною та швидкою. (це цитата з офіційного підручника доктрини ... але я не бачив набагато більше пояснень)
  • ORM повинен виконувати менше роботи (порівняно з двома попередніми способами), а отже, повинен мати кращі результати.

3
@ waaghals. Про ваші коментарі до каскаду = {"remove"} ==> У мене є взаємозв'язок ManyToMany між статтею сутності та категорією. Коли я видаляю статтю ($ em-> remove ($ article);), вона видаляє всі категорії, пов’язані з цією статтею НАВІТИ, якщо ці категорії також пов’язані з іншими статтями. тому я б сказав, що воно не поводиться так, як ви пишете.
Alexis_D

2
@ waaghals. Про ваші коментарі щодо orphanRemoval = "true" На офіційних сторінках доктрини цитується речення, яке я написав: "сутність на зворотній стороні видаляється, коли суб'єктом власності є сторона, і вона не є власністю жодних інших". вчення = сиротавидалення .
Alexis_D

1
@Alexis_D, повністю згідний з вашими коментарями Відповідь неправильна і може по-справжньому заплутати для новачків
Степан Юдін,


Посилання @VictorS дуже чітке. Я більше не працюю з Doctrine, тому відчуваю, що не можу оновити свою відповідь, не знаючи з перших вуст, як це працює. Якби хтось зміг оновити мою відповідь, це було б чудово.
Waaghals
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.