我目前正在使用使用节点表中的节点的数据结构。它是自引用的,因为它具有id和parent_id列。亲子关系是一对多的。意味着多个节点可以具有相同的parent_id。这也可以向下扩展为可变数量的级别。
问题是我不能只删除一个父对象,因为它在外键约束下失败。很好,因为我不想让孩子们成为孤儿。但是,这确实意味着我必须递归地遍历所有子项,直到达到最低级别,删除该子项,然后再进行备份。
到目前为止我还没有运气。这是我的“最佳”尝试,但是转储时toRemove数组始终为空。
/**
* @var array
*/
private $toRemove;
/**
* constructor.
*
* @param array $toRemove
*/
public function __construct(
EntityManagerInterface $entityManager,
array $toRemove = []
)
{
$this->toRemove = $toRemove;
}
someMainFunc(blabla)
{
foreach ($nodes as $node) {
$this->removeChildrenFromLowestLevelUp($node)
}
dump($this->toRemove);die;
}
public function removeChildrenFromLowestLevelUp(Node $node)
{
if (null === $node->getChildren()) {
// Node has no children, add to toRemove array
$this->toRemove[] = $node;
}
/** @var Node $child */
foreach ($node->getChildren() as $child) {
$this->removeChildrenFromLowestLevelUp($child);
}
}
我知道互联网上有很多解决方案,但是我无法完全按照我想要的方式来做。
感谢您的帮助!
您不想这样做。
首先,这意味着很多查询和内存操作。其次,这是对轮子的彻底改造,因为这样的机制已经在数据库和学说中都实现了。
您可以在教义级别使用此关系的映射中的cascade:remove
选项进行此操作。Check documentation了解更多详细信息。
请记住,正如文档所述,所有相关对象将从DB加载到内存中,然后删除。这也意味着一些不必要的查询。
实现此目标的第二种方法是使用SQL的ON DELETE CASCADE
,它执行类似的操作,但在数据库级别。您可以在映射的Doctrine by using onDelete=CASCADE
选项中进行设置。
根据您的描述,我建议您选择第二种方法。