2015-11-03 14 views
5

Utilizzando Symfony e Doctrine, sto scrivendo un componente che popola il database con le voci di entità arbitrarie durante la distribuzione di un'applicazione.Doctrine2: grafico delle dipendenze per un insieme di entità

Voglio rendere questo componente generico, quindi sto cercando di risolvere automaticamente le dipendenze tra entità e inserirle nell'ordine corretto.

Attualmente sto ottenere le dipendenze di ogni singola entità attraverso i metadati entità, in modo ricorsivo:

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; 
} 

Il risultato è, ovviamente, un elenco dei seguenti tipi:

// 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" => [] 
] 

Il passo successivo sarebbe si applichi un certo tipo di ordinamento topologico alla lista, immagino.

Tuttavia, non sono sicuro di poter utilizzare un algoritmo generico qui o se sto dimenticando qualcosa. Soprattutto perché le entità non sono necessariamente correlate (in modo che, in effetti, potremmo avere più di un grafico di dipendenza).

Inoltre, mi auguro che ci sia qualche funzionalità di Doctrine interna che possa fare l'ordinamento per me.

Quindi quale sarebbe il modo più affidabile per ordinare un insieme arbitrario di entità Doctrine? Esiste una funzionalità di Doctrine riutilizzabile?

risposta

0

Quindi, dopo aver scavato per un po 'il codice sorgente di Doctrine, ho scoperto che hanno effettivamente implementato l'ordinamento topologico (DFS per quella materia). È implementato in Doctrine\ORM\Internal\CommitOrderCalculator.

E dove viene utilizzato questo CommitOrderCalculator? In UnitOfWork, ovviamente.

Così, invece di calcolare manualmente il corretto ordine, ho solo bisogno ... per spostare la chiamata alla $em->flush() fuori del foreach ciclo che ha attraversato le entità e lasciare UOW fare il lavoro si impegni.

Duh.

Problemi correlati