假设我们有两个实体(Profile
和Address
)。配置文件可以包含许多地址。在那种情况下,我们有:
Profile:
...
fields:
...
oneToMany:
addresses:
targetEntity: Address
mappedBy: profile
orphanRemoval: true
Address:
...
fields:
...
manyToOne:
profile:
targetEntity: Profile
inversedBy: addresses
joinColumn:
name: profile_id
referencedColumnName: id
onDelete: cascade
现在,如果删除包含许多地址的配置文件:
$em->remove($profile);
如何删除地址?
Doctrine 是否会获取与此配置文件相关的所有地址,然后将其删除或仅删除配置文件并让数据库处理这些地址?
我找到了一些关于 Hibernate 的答案,但没有关于 Doctrine 的答案。
编辑:从条款一书
添加三条音符1.如果关联被标记为CASCADE = REMOVE,则Doctrine 2将获取此关联。如果是单一关联,它会将此实体传递给
EntityManager#remove()
。如果关联是一个集合,Doctrine将遍历其所有元素并将它们传递给EntityManager#remove()
。在这两种情况下,级联删除语义都是递归应用的。对于大型对象图,这种删除策略可能非常昂贵。2.使用DQL DELETE语句允许您使用单个命令删除某个类型的多个实体,而不会保留这些实体。这可以非常有效地从数据库中删除大对象图。
3.使用外键语义onDelete =“CASCADE”可以强制数据库在内部删除所有关联的对象。这个策略有点难以实现,但可以非常强大和快速。 您应该知道,使用策略1(
CASCADE=REMOVE
)完全绕过任何外键onDelete=CASCADE
选项,因为Doctrine将显式地提取并删除所有关联的实体。 / p>
答案 0 :(得分:3)
我做了一个测试:
我首先抓取Profile
(仅profile
没有加入)并将其传递给$em->remove($profile)
,然后 doctrine 运行另一个获取与Address
相关的所有Profile
的查询(一个查询)及之后, doctrine为与Profile
相关的每个地址运行删除查询,在最后它删除Profile
。
所以,我可以说 orphanRemoval是另一种类型的级联,正如教义所说:
orphanRemoval :只有在从集合中删除实体时才有其他级联概念
和orphanRemoval
绕过onDelete
。
答案 1 :(得分:1)
Doctrine手册中有orphan removal部分。还有another question澄清onDelete: cascade
。我希望这两个链接可以帮助您进一步理解该主题。
另外,请确保在$em->remove($profile);
之后调用$em->flush();
操作将本地工作单元同步到数据库。