2017-12-29 56 views
0

クエリビルダーでそれをどのように表現するかで、左結合のネイティブSQLクエリがありますか?Doctrine QueryBuilderはleftJoinのON条件を変更する必要があります

$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 

これをクエリビルダーで表現する必要があります。しかしUserエンティティでは、別のテーブルを使わずにManyToMany関係を持っています。私が左にしようとすると、WITHという条件がこれと同じではありません。私はON

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

Userエンティティ

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

CostObjectエンティティ

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; 

と条件なしの私のクエリビルダ

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

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

この私のために関係を変更する必要があります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 

この例では、私はON関係条件LEFT JOIN users u3_ ON u3_.id = c4_.user_idを参照してください。そして私は、ネイティブSQLで

は、今私は

 $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' 
      ) 
     ) 

を持っていますが、私は私のSQLでは、WITH条件を使用した場合、エラー

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

を得たように、私はまだIDで関係を持って表現し、それを変更する必要がその必要はありません

  ->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))) 

私はusers u3_ ON u3_.id = c4_.user_id ANDを意味しますが、nativ私たちが持っているクエリLEFT JOIN cost_object_managers AS com ON com.cost_object_id = co.id OR com.cost_object_id = co.parent_id

ON条件タイプでクエリビルダーでどのように再現していますか?

+0

私はSymfonyを使用しました。そして、私はQuery Builderが必要です。 –

答えて

0

クエリがあり、それが機能する場合は、DQLまたはQueryBuilderのプログラム構文に変換するための作業をすべて行う必要はありません。 Doctrineのネイティブクエリを使用して、必要に応じて結果をオブジェクトにマップすることができます。あなたが複数のIDのが返されることを期待する場合にも$query->getResult()を使用することができます

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

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

:ちょうどカスタムリポジトリとそれにおおよそ次のようになり、新しいメソッドを作成します。

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

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

あなたはまた、より詳細な説明といくつかのより多くの例についてはDoctrineのマニュアルを確認することができます:それとも、全体のタスク・オブジェクトをしたい場合ResultSetMappingを使用http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/native-sql.html $のRSM )。

+0

素晴らしいアドバイス*あなたがクエリを持っていてそれがうまくいけば、それをDQLに変換するすべての作業をする必要はありません* –

+1

私の場合はクエリビルダクエリが必要です –

関連する問題