我试图做一个简单的例子,以学习如何从父表中删除行,并使用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;
}
这些表是在数据库上正确创建的,但是没有创建On Delete Cascade选项 . 我究竟做错了什么?
2 回答
学说中有两种级联:
1)ORM级别 - 在关联中使用
cascade={"remove"}
- 这是在UnitOfWork中完成的计算,不会影响数据库结构 . 删除对象时,UnitOfWork将遍历关联中的所有对象并将其删除 .2)数据库级别 - 在关联的joinColumn上使用
onDelete="CASCADE"
- 这会将On Delete Cascade添加到数据库中的外键列:我还想指出你现在拥有cascade = {“remove”}的方式,如果你删除了一个Child对象,这个级联将删除Parent对象 . 显然不是你想要的 .
这是一个简单的例子 . 联系人具有一对多的关联电话号码 . 删除联系人时,我希望删除所有关联的电话号码,因此我使用ON DELETE CASCADE . 通过phone_numbers中的外键实现一对多/多对一关系 .
通过向外键约束添加“ON DELETE CASCADE”,将在删除相关联系人时自动删除phone_numbers .
现在,当删除联系人表中的一行时,将自动删除其所有关联的phone_numbers行 .
要在Doctrine中实现相同的功能,要获得相同的DB级别"ON DELETE CASCADE" behavoir,请使用 onDelete="CASCADE" 选项配置@JoinColumn .
如果你现在这样做
您将看到将在第一个原始SQL示例中生成相同的SQL