1

エンティティのコレクション (つまり、リレーショナル専門用語ではテーブル) をクリーンアップしようとしています。これらのエンティティは のインスタンスでありColor、Doctrine 2 を使用してすべての参照されていない を削除するスクリプトを実行したいと考えていますColor。問題はColor、システム内の他の多くのエンティティによって参照されることです。したがって、次の 2 つの選択肢が考えられます。

  1. すべての色を繰り返しColor、システム上の他のエンティティの特定への参照が存在するかどうかを手動で確認し、参照がない場合は削除します。
  2. すべての色を反復処理して 1 つを削除しようとします。その色への参照がある場合は、整合性制約違反が原因で EM によって発生した例外をキャッチします。そのため、失敗した色を無視して次へ進みます。

明らかに、2 番目の選択肢は最初の選択肢よりも単純なので、それを試してみました。私が抱えていた問題は、エンティティの削除が失敗した場合、EM が例外をスローするだけでなく、エンティティ マネージャーを閉じると、それを使用して残りの色を削除できなくなることです!

Doctrine 2 でクラスのcommitメソッドをチェックすると、実際には...UnitOfWork

try {
    ... //Execute queries

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

    throw $e;
}

私がやろうとしていることを達成する方法はありますか (おそらく Entity Manager を再度開く)?
もっと良い方法があると思いますか?
Doctrine がこの動作をするのはなぜですか?

また、Symfony 2 で Doctrine 2 を使用していることにも注意してください。

4

2 に答える 2

1

理想的にはorphanRemoval、関係を定義して、削除を気にする必要がないようにします。それ以外に、私は今3つの解決策を考えることができます..

まず、テーブルを参照するときにCASCADEin を使用しますか?ON DELETEcolors

1)

使用する場合はCASCADE、ここで説明されているように Doctrine のバッチ処理を実装することをお勧めします: BULK DELETEですが、ここで$batchSizeは正確に 1 になります。

2)

どういうわけか、上記のソリューションはあまり効率的ではないと思います。また、次の方法でもこれを達成できます。

  • エンティティを参照するエンティティを調べて、配列にColor収集idします。Color
  • その配列が空でない場合は、次を実行して、通常どおりパラメーターを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 に答える