2015-11-03 11 views
5

SymfonyとDoctrineを使用して、アプリケーションのデプロイ時に任意のエンティティのエントリをデータベースに取り込むコンポーネントを作成しています。Doctrine2:エンティティセットの依存関係グラフ

このコンポーネントを汎用的にしたいので、エンティティ間の依存関係を自動的に解決し、正しい順序で挿入しようとしています。

私は現在、再帰的に、エンティティのメタデータを介して単一のエンティティの依存関係を取得しています:

public function getEntityDeps($eName) 
{ 
    $deps = []; 

    foreach ($this->entityManager->getClassMetadata($eName)->getAssociationMappings() as $mapping) 
    { 
     $deps[] = $mapping['targetEntity']; 
     $deps = array_merge($deps, $this->getEntityDeps($mapping['targetEntity'])); 
    } 

    return $deps; 
} 

結果は明らかに、以下のようなもののリストです:

// NOTE: The real list of course contains class names instead of entity aliases. 
[ 
    "FooBundle:EntityA" => [], 
    "FooBundle:EntityB" => ["FooBundle:EntityA", "FooBundle:EntityC"], 
    "FooBundle:EntityC" => ["FooBundle:EntityA"], 
    "BarBundle:EntityA" => ["BarBundle:EntityB"], 
    "BarBundle:EntityB" => [] 
] 

次のステップを希望いくつかのタイプのトポロジカルソートをリストに適用する必要があります。

しかし、ここでジェネリックアルゴリズムを使用できるのか、何か忘れているのかどうかはわかりません。特にエンティティは必ずしも関連していないので(実際には、複数の依存関係グラフが存在する可能性があります)。

また、Doctrineの内部機能があり、私のソートを行うことができます。

Doctrineエンティティの任意のセットをソートする最も信頼できる方法は何でしょうか?再利用可能なDoctrineの機能がありますか?

答えて

0

Doctrineのソースコードをしばらく掘り下げた後、私は実際にトポロジカルソート(DFS)を実装していることがわかりました。 Doctrine\ORM\Internal\CommitOrderCalculatorに実装されています。

ここではCommitOrderCalculatorは使用されていますか?もちろんUnitOfWorkにあります。

正しいコミット順を手作業で計算するのではなく、foreachのループの外側にある$em->flush()の呼び出しを移動して、UOWに作業をさせるだけでした。

Duh。