2017-12-29 29 views
0

Ich habe native SQL-Abfrage mit linken Join, wenn on mit oder Bedingung, wie es in Query Builder darstellen?Doctrine QueryBuilder muss ändern ON-Bedingung für leftJoin

$query = " SELECT te.id 
      FROM task_executions AS te 
      INNER JOIN tasks AS t ON t.id = te.task_id 
      LEFT JOIN cost_objects AS co ON co.id = t.cost_object_id 
      LEFT JOIN cost_object_managers AS com ON com.cost_object_id = co.id OR com.cost_object_id = co.parent_id 

und ich brauche es in Query Builder darstellen. Aber in User Einheit habe ich ManyToMany Beziehung, ohne separate Tabelle und wenn ich links versuchen, Join WITH Bedingung ist dies nicht das gleiche, was ich brauche. Ich brauche Beziehung ON für

ändern
LEFT JOIN cost_object_managers AS com ON com.cost_object_id = co.id OR com.cost_object_id = co.parent_id 

Benutzer Einheit

class User 
{ 
... 
/** 
* @ORM\ManyToMany(targetEntity="CostObject", mappedBy="users") 
*/ 
private $costObjects; 
} 

CostObject Einheit

class CostObject 
{ 
    /** 
* @var CostObject 
* 
* @ORM\ManyToOne(targetEntity="CostObject", inversedBy="children") 
* @ORM\JoinColumns({ 
* @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE") 
* }) 
*/ 
private $parent; 

    /** 
* @var ArrayCollection 
* 
* @ORM\ManyToMany(targetEntity="User", inversedBy="costObjects") 
* @ORM\JoinTable(name="cost_object_managers", 
*  joinColumns={@ORM\JoinColumn(name="cost_object_id", referencedColumnName="id", onDelete="CASCADE")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")} 
*) 
*/ 
private $users; 

und meine Query Builder ohne Bedingung

 $qb->select('te') 
     ->from('AppBundle:TaskExecution', 'te') 
     ->innerJoin('te.task', 't') 

     ->leftJoin('t.costObject', 'co') 
     ->leftJoin('co.users', 'com') 

dieses i s $query->getSQL()

SELECT some_name FROM task_executions t0_ INNER JOIN tasks t1_ ON t0_.task_id = t1_.id LEFT JOIN cost_objects c2_ ON t1_.cost_object_id = c2_.id LEFT JOIN cost_object_managers c4_ ON c2_.id = c4_.cost_object_id LEFT JOIN users u3_ ON u3_.id = c4_.user_id ORDER BY t0_.execution_start DESC 

In diesem Beispiel sehe ich ON Beziehung Zustand LEFT JOIN users u3_ ON u3_.id = c4_.user_id. Und braucht es wie native in SQL ändern

Jetzt habe ich

 $qb->select('te') 
     ->from('AppBundle:TaskExecution', 'te') 
     ->innerJoin('te.task', 't') 
     ->leftJoin('t.costObject', 'co') 
     ->leftJoin(
      'co.users', 
      'com', 
      Join::ON, 
      $qb->expr()->orX(
       'co = com.costObjects', 
       'co.parent = com.costObjects' 
      ) 
     ) 

aber erhielt Fehler

[Syntax Error] line 0, col 112: Error: Expected end of string, got 'ON' 

wenn ich WITH Zustand verwendet, in meinem SQL stellen ich habe noch Beziehung von id, I nicht brauchen, dass

  ->leftJoin(
      'co.users', 
      'com', 
      Join::WITH, 
      $qb->expr()->orX(
       'co MEMBER OF com.costObjects', 
       'co.parent MEMBER OF com.costObjects' 
      ) 
     ) 

LEFT JOIN users u3_ ON u3_.id = c4_.user_id AND (EXISTS (SELECT 1 FROM cost_object_managers c5_ INNER JOIN cost_objects c6_ ON c5_.cost_object_id = c6_.id WHERE c5_.user_id = u3_.id AND c6_.id IN (c2_.id)) OR EXISTS (SELECT 1 FROM cost_object_managers c5_ INNER JOIN cost_objects c6_ ON c5_.cost_object_id = c6_.id WHERE c5_.user_id = u3_.id AND c6_.id IN (c2_.parent_id))) 

ich meine users u3_ ON u3_.id = c4_.user_id AND aber in Nativ e-Abfrage haben wir nur LEFT JOIN cost_object_managers AS com ON com.cost_object_id = co.id OR com.cost_object_id = co.parent_id

Wie es im Query Builder mit ON Bedingungstyp reproduzieren?

+0

Ich habe Symfony verwendet. Und ich brauche Query Builder repräsentieren –

Antwort

0

Wenn Sie die Abfrage haben und es für Sie funktioniert, müssen Sie nicht alle Arbeiten ausführen, um sie in DQL oder die programmatische Syntax von QueryBuilder umzuwandeln. Sie können einfach die native Abfrage von Doctrine verwenden und dann - falls erforderlich - das Ergebnis Ihrem Objekt zuordnen. Erstellen Sie einfach ein eigenes Repository und in ihm eine neue Methode, die das sieht ungefähr so:

public function findTaskExecutionBy...() 
{ 
    $query = $this->entityManager->createNativeQuery('SELECT te.id FROM ...'); 

    return $query->getSingleScalarResult(); // If it's just one id you expect 
} 

Sie auch $query->getResult() verwenden können, wenn Sie mehrere IDs erwarten zurückgegeben werden. Oder verwenden Sie die ResultSetMapping, wenn Sie das gesamte Aufgaben Objekt wollen:

$rsm = new ResultSetMappingBuilder($this->entityManager); 
$rsm->addRootEntityFromClassMetadata('App\Entity\Task', 'te'); 

$query = $this->entityManager->createNativeQuery(
    'SELECT te.* FROM ...', 

Sie können auch die Lehre Dokumentation prüfen, um eine ausführliche Erklärung und einige weitere Beispiele: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/native-sql.html $ RSM );

+0

Great great advice * Wenn Sie die Abfrage haben und es für Sie funktioniert, müssen Sie nicht alle arbeiten, um es in DQL * –

+1

zu transformieren In meinem Fall brauche ich Query Builder Query –

Verwandte Themen