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


93

Ho provato a raccogliere poche informazioni su coloro che seguono il modo per eliminare automaticamente l'entità figlio quando viene eliminata un'entità padre. Sembra che il modo più comune sia usare una di queste tre annotazioni: cascade = {"remove"} OR orphanRemoval = true OR ondelete = "CASCADE" .

Sono un po 'confuso riguardo al terzo: ondelete = "CASCADE" , poiché le spiegazioni nella documentazione ufficiale di questa dottrina sono molto scarse) e mi piacerebbe se qualcuno potesse confermarmi le seguenti informazioni che ho raccolto e compreso dalla mia ricerca sul rete ed esperienza ...

COSA FA

cascade = {"remove"}
==> l'entità sul lato opposto viene eliminata quando l'entità del lato proprietario è. Anche se sei in molti con altre entità secondarie proprietarie.
- dovrebbe essere utilizzato nella raccolta (quindi nella relazione OneToMany o ManyToMany)
- implementazione nell'ORM

orphanRemoval = true
==> l'entità sul lato inverso viene eliminata quando l'entità del lato proprietario è E non è più collegata a nessun'altra entità laterale proprietaria. (rif. doctrine official_doc - implementazione
nell'ORM - può essere utilizzato con OneToOne, OnetoMany o ManyToMany

onDelete = "CASCADE"
==> questo aggiungerà On Delete Cascade alla colonna della chiave esterna nel database
- Questa strategia è un po 'complicata da mettere a punto ma può essere molto potente e veloce. (rif. doctrine official_doc ... ma non ho letto altre spiegazioni)
- ORM deve fare meno lavoro (rispetto ai due precedenti modi di fare) e quindi dovrebbe avere prestazioni migliori.

altre informazioni
- tutti questi 3 modi di fare sono implementati su entità di relazione bidirezionale ( giusto ??? )
- usando cascade = {"remove"} bypassa completamente qualsiasi chiave esterna onDelete = CASCADE. (rif. doctrine_official_doc )

ESEMPIO SU COME USARLO IN CODICE

  • orphanRemoval e cascade = {"remove"} sono definiti nella classe di entità inversa.
  • ondelete = "CASCADE" è definito nell'entità proprietario
  • puoi anche scrivere @ORM \ JoinColumn (onDelete = "CASCADE") e lasciare che doctrine gestisca i nomi delle colonne

cascade = {"rimuovi"}

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

orphanRemoval = true

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

onDelete = "CASCATA"

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

Risposte:


61

onDelete="CASCADE" è gestito dal database stesso. cascade={"remove"}è gestito dalla dottrina.

onDelete="CASCADE"è più veloce perché le operazioni vengono eseguite a livello di database invece di doctrine. La rimozione viene eseguita dal server del database e non da Doctrine. Concascade={"remove"} doctrine deve gestire l'entità stessa ed eseguirà controlli extra per vedere se non ha altre entità proprietarie. Quando nessun altro esiste, eliminerà l'entità. Ma questo crea un sovraccarico.


cascade = {"rimuovi"}

  • l'entità sul lato opposto viene eliminata quando l'entità sul lato proprietario è. Anche se sei in molti con altre entità secondarie proprietarie.No, se l'entità è di proprietà di qualcos'altro. Non verrà eliminato.
  • dovrebbe essere usato nella raccolta (quindi nella relazione OneToMany o ManyToMany)
  • implementazione nell'ORM

orphanRemoval = "true"

  • l'entità sul lato inverso viene eliminata quando l'entità del lato proprietario è E non è più collegata a nessun'altra entità laterale proprietaria. Non esattamente, questo fa sì che la dottrina si comporti come se non fosse di proprietà di un'altra entità, e quindi la rimuova.
  • implementazione nell'ORM
  • può essere utilizzato con OneToOne, OnetoMany o ManyToMany

onDelete = "CASCATA"

  • questo aggiungerà On Delete Cascade alla colonna della chiave esterna NEL DATABASE
  • Questa strategia è un po 'complicata da mettere a punto, ma può essere molto potente e veloce. (questa è una citazione dal tutorial ufficiale di dottrine ... ma non ho visto molte altre spiegazioni)
  • ORM deve fare meno lavoro (rispetto ai due precedenti modi di fare) e quindi dovrebbe avere prestazioni migliori.

3
@ waaghals. A proposito dei tuoi commenti su cascade = {"remove"} ==> Ho una relazione ManyToMany tra l'entità Articolo e la Categoria. Quando rimuovo un articolo ($ em-> remove ($ article);) rimuove tutte le categorie collegate a questo articolo ANCHE se quelle categorie sono collegate anche ad altri articoli. quindi direi che non si comporta come scrivi.
Alexis_D

2
@ waaghals. Circa i tuoi commenti su orphanRemoval = "true" La frase che ho scritto "l'entità sul lato opposto viene cancellata quando l'entità laterale proprietaria è, e non è di proprietà di altre entità" è citata dalle pagine ufficiali di dottrine. doctrine = orphanremoval .
Alexis_D

1
@Alexis_D, pienamente d'accordo con i tuoi commenti La risposta non è corretta e può essere davvero fonte di confusione per i neofiti
Stepan Yudin

3
Uno degli esempi più chiari che ho letto: gist.github.com/pylebecq/f844d1f6860241d8b025
Victor S

Il link di @VictorS è molto chiaro. Non lavoro più con Doctrine, quindi sento di non poter aggiornare la mia risposta senza sapere in prima persona come funziona. Se qualcuno potesse aggiornare la mia risposta sarebbe fantastico.
Waaghals
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.