用doctrine2删除级联

我试图做一个简单的例子,以了解如何从父表中删除一行,并自动删除使用Doctrine2在子表中匹配的行。

以下是我正在使用的两个实体:

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; } 

表格在数据库上正确创build,但是在On Delete Cascade选项中没有创build。 我究竟做错了什么?

教义中有两种级联:

1)ORM级别 – 在关联中使用cascade={"remove"} – 这是在UnitOfWork中完成的计算,不会影响数据库结构。 当你移除一个对象的时候,UnitOfWork会迭代关联中的所有对象并将它们移除。

2)数据库级别 – 在关联的joinColumn上使用onDelete="CASCADE" – 这会将On Delete Cascade添加到数据库中的外键列:

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

我也想指出,现在你有cascade = {“remove”}的方式,如果删除一个Child对象,这个级联将会删除Parent对象。 显然不是你想要的。

这是一个简单的例子。 联系人具有一个或多个关联的电话号码。 当一个联系人被删除时,我想让所有的联系电话号码也被删除,所以我使用ON DELETE CASCADE。 一对多/多对一关系由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; 

通过在外键约束中添加“ON DELETE CASCADE”,当删除关联的联系人时,phone_numbers将自动被删除。

 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); 

现在当联系人表中的一行被删除时,所有与其关联的电话号码行将被自动删除。

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

为了在Doctrine中实现相同的目的,要获得相同的DB级别“ON DELETE CASCADE”行为,可以使用onDelete =“CASCADE”选项configuration@JoinColumn。

 <?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"; } 

如果你现在这样做

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

您将看到将生成与第一个原始SQL示例中相同的SQL