1

我正在尝试清理实体集合(即关系术语中的表),这些实体是 的实例Color,并且我想运行一个使用 Doctrine 2 删除所有未引用的脚本的脚本Color。问题是Color系统中的许多其他实体都引用了它。所以,我可以想到两个选择:

  1. 遍历所有颜色并手动检查每种颜色是否存在Color对我系统上其他实体上的特定的引用,如果没有引用,则将其删除。
  2. 遍历所有颜色并尝试删除一个,如果有对该颜色的引用,则捕获由违反完整性约束引起的 EM 引发的异常,因此,我确实忽略了失败的颜色并继续下一步。

显然,第二种选择比第一种更简单,所以我试过了。我遇到的问题是,当实体删除失败时,EM 会抛出异常,但也会关闭实体管理器,我不能再使用它来删除剩余的颜色!

我检查了教义 2commit的课程方法UnitOfWork,实际上......

try {
    ... //Execute queries

    $conn->commit();
} catch (Exception $e) {
    $this->em->close();
    $conn->rollback();

    throw $e;
}

有什么方法可以完成我正在尝试做的事情(也许重新打开实体管理器)?
你相信有更好的方法吗?
为什么教义有这种行为?

另请注意,我将 Doctrine 2 与 Symfony 2 一起使用

4

2 回答 2

1

理想情况下,您将orphanRemoval在您的关系中进行定义,这样您就不需要为删除而烦恼。除此之外,我现在可以想到 3 个解决方案..

首先,你在引用表时使用CASCADEin吗?ON DELETEcolors

1)

如果您确实使用CASCADE我建议按照此处所述实施 Doctrine 的批处理:BULK DELETE但在这里您$batchSize将是 1。

2)

不知何故,我认为上述解决方案效率不高,您也可以通过以下方式实现:

  • 遍历引用实体的Color实体并收集idColor数组中。
  • 如果该数组不为空,则执行:并照常DELETE FROM AcmeDemoBundle:Color c WHERE c.id IN (:ids)设置参数。ids

3)

如果您使用CASCADE. 您可以执行原始 sql

DELETE IGNORE FROM color;

在这里,引用的颜色不会被删除并且会引发错误,但由于IGNORE它最终只会作为警告。

希望有些帮助....

于 2012-10-10T22:44:54.353 回答
0

像这样的东西:

// somewhere in ColorRepository.php

$this->createQueryBuilder("o")
    ->leftJoin("o.Relation1", "r1")
    ->leftJoin("o.Relation2", "r2)
    ->where("r1 IS NULL AND r2 IS NULL")
    ->delete() ;

只有当它们不再与 r1 和 r2 有关系并删除它们时,这才应该加载您的实体(颜色)。

于 2012-10-11T03:05:41.133 回答