递归删除最低级别的孩子Symfony / Doctrine

问题描述 投票:0回答:1

我目前正在使用使用节点表中的节点的数据结构。它是自引用的,因为它具有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);
    }
}

我知道互联网上有很多解决方案,但是我无法完全按照我想要的方式来做。

感谢您的帮助!

php symfony doctrine
1个回答
0
投票

您不想这样做。

首先,这意味着很多查询和内存操作。其次,这是对轮子的彻底改造,因为这样的机制已经在数据库和学说中都实现了。

您可以在教义级别使用此关系的映射中的cascade:remove选项进行此操作。Check documentation了解更多详细信息。

请记住,正如文档所述,所有相关对象将从DB加载到内存中,然后删除。这也意味着一些不必要的查询。

实现此目标的第二种方法是使用SQL的ON DELETE CASCADE,它执行类似的操作,但在数据库级别。您可以在映射的Doctrine by using onDelete=CASCADE选项中进行设置。

根据您的描述,我建议您选择第二种方法。

© www.soinside.com 2019 - 2024. All rights reserved.