På slette kaskade med doctrine2

stemmer
200

Jeg prøver å lage et enkelt eksempel for å lære hvordan du sletter en rad fra en overordnet tabell og automatisk slette de samsvarende rader i barnet tabellen ved hjelp Doctrine2.

Her er de to enhetene jeg bruker:

Child.php:

<?php

namespace Acme\CascadeBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name=child)
 */
class Child {

    /**
     * @ORM\Id
     * @ORM\Column(type=integer)
     * @ORM\GeneratedValue(strategy=AUTO)
     */
    private $id;
    /**
     * @ORM\ManyToOne(targetEntity=Father, cascade={remove})
     *
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name=father_id, referencedColumnName=id)
     * })
     *
     * @var father
     */
    private $father;
}

Father.php

<?php
namespace Acme\CascadeBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name=father)
 */
class Father
{
    /**
     * @ORM\Id
     * @ORM\Column(type=integer)
     * @ORM\GeneratedValue(strategy=AUTO)
     */
    private $id;
}

Tabellene er riktig opprettet på databasen, men On Slett Cascade-alternativet er det ikke opprettet. Hva gjør jeg galt?

Publisert på 13/06/2011 klokken 09:12
kilden bruker
På andre språk...                            


2 svar

stemmer
352

Det finnes to typer kaskader i Lære:

1) ORM nivå - anvender cascade={"remove"}i foreningen - dette er en beregning som utføres i den UnitOfWork og påvirker ikke databasestrukturen. Når du fjerner et objekt, vil UnitOfWork iterere over alle objekter i foreningen og fjerne dem.

2) Database nivå - bruker onDelete="CASCADE"på foreningens joinColumn - dette vil legge på Slett Cascade til fremmednøkkelkolonne i databasen:

@ORM\JoinColumn(name="father_id", referencedColumnName="id", onDelete="CASCADE")

Jeg ønsker også å påpeke at måten du har din cascade = { "fjerne"} akkurat nå, hvis du sletter et barn objekt, vil dette kaskade fjerne det overordnede objektet. Åpenbart ikke hva du ønsker.

Svarte 13/06/2011 kl. 18:40
kilden bruker

stemmer
39

Her er enkelt eksempel. En kontakt har en til mange forbundet telefonnumre. Når en kontakt er slettet, jeg vil at alle assosierte telefonnumre også bli slettet, så jeg bruker ON DELETE CASCADE. En-til-mange / mange-til-en forhold er implementert med å fremmednøkkel i phone_numbers.

CREATE TABLE contacts
 (contact_id BIGINT AUTO_INCREMENT NOT NULL,
 name VARCHAR(75) NOT NULL,
 PRIMARY KEY(contact_id)) ENGINE = InnoDB;

CREATE TABLE phone_numbers
 (phone_id BIGINT AUTO_INCREMENT NOT NULL,
  phone_number CHAR(10) NOT NULL,
 contact_id BIGINT NOT NULL,
 PRIMARY KEY(phone_id),
 UNIQUE(phone_number)) ENGINE = InnoDB;

ALTER TABLE phone_numbers ADD FOREIGN KEY (contact_id) REFERENCES \
contacts(contact_id) ) ON DELETE CASCADE;

Ved å legge til "ON DELETE CASCADE" til fremmednøkkelbegrensning, vil phone_numbers automatisk bli slettet når tilhørende kontakten slettes.

INSERT INTO table contacts(name) VALUES('Robert Smith');
INSERT INTO table phone_numbers(phone_number, contact_id) VALUES('8963333333', 1);
INSERT INTO table phone_numbers(phone_number, contact_id) VALUES('8964444444', 1);

Nå når en rad i kontakt tabellen slettes, vil alle de tilknyttede phone_numbers rader automatisk bli slettet.

DELETE TABLE contacts as c WHERE c.id=1; /* delete cascades to phone_numbers */

For å oppnå det samme i Lære, for å få den samme DB-nivå "ON DELETE CASCADE" behavoir, konfigurerer du @JoinColumn med onDelete = "Cascade" alternativet.

<?php
namespace Entities;

use Doctrine\Common\Collections\ArrayCollection;

/**
 * @Entity
 * @Table(name="contacts")
 */
class Contact 
{

    /**
     *  @Id
     *  @Column(type="integer", name="contact_id") 
     *  @GeneratedValue
     */
    protected $id;  

    /** 
     * @Column(type="string", length="75", unique="true") 
     */ 
    protected $name; 

    /** 
     * @OneToMany(targetEntity="Phonenumber", mappedBy="contact")
     */ 
    protected $phonenumbers; 

    public function __construct($name=null)
    {
        $this->phonenumbers = new ArrayCollection();

        if (!is_null($name)) {

            $this->name = $name;
        }
    }

    public function getId()
    {
        return $this->id;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function addPhonenumber(Phonenumber $p)
    {
        if (!$this->phonenumbers->contains($p)) {

            $this->phonenumbers[] = $p;
            $p->setContact($this);
        }
    }

    public function removePhonenumber(Phonenumber $p)
    {
        $this->phonenumbers->remove($p);
    }
}

<?php
namespace Entities;

/**
 * @Entity
 * @Table(name="phonenumbers")
 */
class Phonenumber 
{

    /**
    * @Id
    * @Column(type="integer", name="phone_id") 
    * @GeneratedValue
    */
    protected $id; 

    /**
     * @Column(type="string", length="10", unique="true") 
     */  
    protected $number;

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

    public function __construct($number=null)
    {
        if (!is_null($number)) {

            $this->number = $number;
        }
    }

    public function setPhonenumber($number)
    {
        $this->number = $number;
    }

    public function setContact(Contact $c)
    {
        $this->contact = $c;
    }
} 
?>

<?php

$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);

$contact = new Contact("John Doe"); 

$phone1 = new Phonenumber("8173333333");
$phone2 = new Phonenumber("8174444444");
$em->persist($phone1);
$em->persist($phone2);
$contact->addPhonenumber($phone1); 
$contact->addPhonenumber($phone2); 

$em->persist($contact);
try {

    $em->flush();
} catch(Exception $e) {

    $m = $e->getMessage();
    echo $m . "<br />\n";
}

Hvis du nå gjøre

# doctrine orm:schema-tool:create --dump-sql

vil du se at den samme SQL vil bli generert som i første, rå-SQL eksempel

Svarte 08/12/2011 kl. 03:06
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more