cascade = {"remove"} VS orphanRemoval = true VS ondelete = "CASCADE

92

Ich habe versucht, einige Informationen über die folgenden Methoden zum automatischen Löschen einer untergeordneten Entität zu sammeln, wenn eine übergeordnete Entität gelöscht wird. Scheint, dass der häufigste Weg darin besteht, eine dieser drei Anmerkungen zu verwenden: cascade = {"remove"} OR orphanRemoval = true OR ondelete = "CASCADE" .

Ich bin etwas verwirrt über die dritte: ondelete = "CASCADE" , da Erklärungen in der offiziellen Dokumentation der Doktrin zu dieser sehr selten sind) und ich würde mich freuen , wenn mir jemand die folgenden Informationen bestätigen könnte, die ich aus meinen Recherchen über die Netz und Erfahrung ...

WAS ES MACHT

cascade = {"remove"}
==> Die Entität auf der inversen Seite wird gelöscht, wenn die Entität auf der Besitzerseite ist. Selbst wenn Sie in einer Vielzahl von Unternehmen mit anderen Eigentümern sind.
- sollte bei der Erfassung verwendet werden (also in der OneToMany- oder ManyToMany-Beziehung)
- Implementierung im ORM

orphanRemoval = true
==> Die Entität auf der inversen Seite wird gelöscht, wenn die Entität auf der Besitzerseite UND ist und nicht mehr mit einer anderen Entität auf der Besitzerseite verbunden ist. (Ref. Doctrineicial_doc - Implementierung im ORM
- kann mit OneToOne, OnetoMany oder ManyToMany verwendet werden

onDelete = "CASCADE"
==> Dadurch wird On Delete Cascade zur Fremdschlüsselspalte in der Datenbank hinzugefügt.
Diese Strategie ist etwas schwierig zu korrigieren, kann jedoch sehr leistungsfähig und schnell sein. (Ref. Doctrine offiziell_doc ... aber ich habe keine weiteren Erklärungen gelesen)
- ORM muss weniger Arbeit leisten (im Vergleich zu den beiden vorherigen Methoden) und sollte daher eine bessere Leistung haben.

andere Informationen
- all diese drei Methoden werden auf bidirektionalen Beziehungsentitäten implementiert ( rechts ??? )
- mit cascade = {"remove"} wird jeder Fremdschlüssel onDelete = CASCADE vollständig umgangen. (Ref. Doctrine_official_doc )

BEISPIEL FÜR DIE VERWENDUNG IM CODE

  • orphanRemoval und cascade = {"remove"} werden in der inversen Entitätsklasse definiert.
  • ondelete = "CASCADE" ist in der Eigentümerentität definiert
  • Sie können auch einfach @ORM \ JoinColumn (onDelete = "CASCADE") schreiben und die Spalte die Spaltennamen behandeln lassen

cascade = {"remove"}

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

orphanRemoval = true

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

onDelete = "CASCADE"

/** 
* @ManyToOne(targetEntity="Contact", inversedBy="phonenumbers")
* @JoinColumn(name="contact_id", referencedColumnName="contact_id", onDelete="CASCADE")
*/ 
protected $contact; 
Alexis_D
quelle
1
es hat eine gute Erklärung stackoverflow.com/questions/25515007/…
Gregsparrow

Antworten:

60

onDelete="CASCADE"wird von der Datenbank selbst verwaltet. cascade={"remove"}wird von der Lehre verwaltet.

onDelete="CASCADE"ist schneller, weil die Operationen auf Datenbankebene statt durch Doktrin ausgeführt werden. Das Entfernen wird vom Datenbankserver und nicht von Doctrine durchgeführt. With cascade={"remove"}Doctrine muss die Entität selbst verwalten und führt zusätzliche Überprüfungen durch, um festzustellen, ob sie keine anderen besitzenden Entitäten hat. Wenn keine andere vorhanden ist, wird die Entität gelöscht. Dies schafft jedoch Overhead.


cascade = {"remove"}

  • Die Entität auf der inversen Seite wird gelöscht, wenn die Entität auf der Besitzerseite ist. Selbst wenn Sie in einer Vielzahl von Unternehmen mit anderen Eigentümern sind. Nein, wenn die Entität etwas anderem gehört. Es wird nicht gelöscht.
  • sollte für die Sammlung verwendet werden (also in der OneToMany- oder ManyToMany-Beziehung)
  • Implementierung im ORM

orphanRemoval = "true"

  • Die Entität auf der inversen Seite wird gelöscht, wenn die Entität auf der Besitzerseite UND NICHT mehr mit einer anderen Entität auf der Besitzerseite verbunden ist. Nicht genau, dies führt dazu, dass sich die Lehre so verhält, als ob sie keiner anderen Entität gehört, und sie somit entfernt.
  • Implementierung im ORM
  • kann mit OneToOne, OnetoMany oder ManyToMany verwendet werden

onDelete = "CASCADE"

  • Dadurch wird der Fremdschlüsselspalte IN DER DATENBANK On Delete Cascade hinzugefügt
  • Diese Strategie ist etwas schwierig, aber sie kann sehr leistungsfähig und schnell sein. (Dies ist ein Zitat aus dem offiziellen Tutorial der Doktrin ... aber ich habe nicht viel mehr Erklärungen gesehen)
  • ORM muss weniger arbeiten (im Vergleich zu den beiden vorherigen Methoden) und sollte daher eine bessere Leistung haben.
Waaghals
quelle
3
@ waaghals. Über Ihre Kommentare zur Kaskade = {"remove"} ==> Ich habe eine ManyToMany-Beziehung zwischen Entitätsartikel und Kategorie. Wenn ich einen Artikel entferne ($ em-> remove ($ article);), werden alle mit diesem Artikel verknüpften Kategorien AUCH entfernt, wenn diese Kategorien auch mit anderen Artikeln verknüpft sind. Ich würde also sagen, dass es sich nicht so verhält, wie Sie schreiben.
Alexis_D
2
@ waaghals. Über Ihre Kommentare zu orphanRemoval = "true" Der Satz, den ich geschrieben habe "Die Entität auf der umgekehrten Seite wird gelöscht, wenn die Entität auf der Besitzerseite ist und keiner anderen Entität gehört", wird auf offiziellen Seiten der Doktrin zitiert. Doktrin = Waisenentfernung .
Alexis_D
1
@Alexis_D, voll und ganz mit Ihren Kommentaren einverstanden Die Antwort ist falsch und kann für Neulinge sehr verwirrend sein
Stepan Yudin
3
Eines der klareren Beispiele, die ich gelesen habe: gist.github.com/pylebecq/f844d1f6860241d8b025
Victor S
Der Link von @VictorS ist sehr klar. Ich arbeite nicht mehr mit Doctrine, daher kann ich meine Antwort nicht aktualisieren, ohne aus erster Hand zu wissen, wie sie funktioniert. Wenn jemand meine Antwort aktualisieren könnte, wäre das großartig.
Waaghals