2016-05-27 9 views
1

Ich arbeite derzeit an einer API mit dem folgenden Stapel;Dynamisch eifrig laden tiefe Beziehungen mit Doctrine

  • Symfony (3)
  • FOSRestBundle
  • Fractal

Ich wollte die Möglichkeit, anzugeben, über Abfrageparameter zu integrieren, die Beziehungen sind, wenn ein Unternehmen/Sammlung abrufen, z.B;

[GET] /users?include=friends.addresses 

Fractal comes with the ability to handle includes Da dies jedoch um den Serialisierungspunkt des Ansprechens Gebäudes geschieht, wird jede verbundene Einheit über träges Laden abgerufen, wodurch zusätzliche Abfragen auszulösen.

Gibt es eine Möglichkeit, Doctrine mitzuteilen, dass beim Abrufen einer Sammlung dynamisch die angegebenen Beziehungen abgerufen werden sollen? Ive gesehen the following from the Doctrine docs which shows how to dynamically change the fetch mode jedoch scheint dies nur mit Zuordnungen auf der Zieleinheit (friends im obigen Beispiel) und nicht tiefere Beziehungen (addresses von friends in dem Beispiel) zu arbeiten.

Danke!

Antwort

2

Wenn ich mich richtig erinnere, kann man Relationen "preloadieren", indem man sie zusammenfügt, anstatt den Lazy Loading-Mechanismus damit umgehen zu lassen. Eine Idee könnte darin bestehen, einen Dienst zu erstellen, der basierend auf Ihren Kriterien einen Abfrage-Generator erstellt. Dies ist ein grober Schnipsel von dem, was ich meine:

class EagerService 
{ 
    protected $em; 

    public function __construct(EntityManager $em) 
    { 
     $this->em = $em; 
    } 

    public function resolveIncludes($class, $alias, $includes) 
    { 
     // Parse includes into an array 
     if (strpos($includes, '.') !== false) { 
      $relations = explode('.', $includes); 
     } else { 
      $relations = [$includes]; 
     } 

     // The next relation is owned by the previous one, so we keep track of the previous relation 
     $previousRelation = $alias; 
     $qb = $em->getRepository($class)->getQueryBuilder($previousRelation); 
     foreach ($relations as $relation) { 
      // Add inner joins to the query builder referencing the new relation 
      $qb->innerJoin("{$previousRelation}.{$relation}", $relation); 
      $previousRelation = $relation; 
     } 

     // Return query builder or the result of the query 
     return $qb; 
    } 
} 
+0

Vielen Dank für das scheint, wie die beste Lösung, damit ich Glad darauf –

+1

bauen werde ich helfen konnte. Ich habe gesehen, dass ich vergessen habe, '$ str' um' $ includes' zu ändern, also habe ich das behoben. –

Verwandte Themen