php - 递归删除最低级别的孩子 Symfony/Doctrine
问题描述
我目前正在使用使用节点表中的节点的数据结构。它是自引用的,因为它有一个 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);
}
}
我知道互联网上有很多解决方案,但我不能让他们中的任何一个按照我想要的方式去做。
谢谢你的帮助!
解决方案
你不想那样做。
首先,这意味着大量的查询和内存操作。其次,这是对轮子的再发明,因为这样的机制已经在数据库和 Doctrine 中实现了。
您可以在 Doctrine 级别使用cascade:remove
此关系映射中的选项来执行此操作。查看文档以获取更多详细信息。
请记住,如文档中所述,所有相关对象都将从数据库加载到内存中,然后删除。这也意味着一些不必要的查询。
实现此目的的第二种方法是使用 SQL ON DELETE CASCADE
,它做类似的事情,但在数据库级别。您可以使用映射中的选项在Doctrine中设置它。onDelete=CASCADE
根据您的描述,我会推荐第二种选择。
推荐阅读
- reactjs - 更新从本地存储中获取的 formData
- google-cloud-platform - gcloud 对 add-iam-policy-binding 的混淆
- r - 在 R 中的查找表上完全匹配字符串
- react-native - 如何在 React Native 中将我的屏幕分成三个具有不同文本内容的部分
- python - 如何使用 python 从网页提要中下载图像
- django - 带有此电子邮件的模型已存在于 django 中
- python - 如何将压缩的 TSV 文件读取到 Databricks 上的数据框?
- discord.js - 日志 discord.js 中的 Missiong 权限错误
- karma-runner - 在 Edge 和 azure 管道上进行 Karma 测试
- excel - {请忽略,发现语法错误} xlsxwriter 公式结果在 Excel 中打开时为 0