J'aimerais construire le code SQL suivant à l'aide du générateur de requêtes de Doctrine:
select c.*
from customer c
join phone p
on p.customer_id = c.id
and p.phone = :phone
where c.username = :username
J'ai d'abord essayé
$qb->select('c')
->innerJoin('c.phones', 'p', Join::ON, $qb->expr()->andx(
$qb->expr()->eq('p.customerId', 'c.id'),
$qb->expr()->eq('p.phone', ':phone')
))
->where('c.username = :username');
Mais j'obtiens l'erreur suivante
Error: expected end of string, got 'ON'
Puis j'ai essayé
$qb->select('c')
->innerJoin('c.phones', 'p')
->where('c.username = :username')
->andWhere('p.phone = :phone');
qui semble fonctionner. Cependant, est-ce que quelqu'un sait ce qui ne va pas avec la première tentative? J'aimerais faire fonctionner le premier car il ressemble plus étroitement à la structure de SQL. Merci d'avance!
Note: Je sais que nous pouvons aussi écrire mysql ou dql en natif avec Doctrine, mais je préférerais que le constructeur de requêtes soit créé.
EDIT: Ci-dessous le code complet
namespace Cyan\CustomerBundle\Repository;
use Cyan\CustomerBundle\Entity\Customer;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join;
class CustomerRepository extends EntityRepository
{
public function findCustomerByPhone($username, $phone)
{
$qb = $this->createQueryBuilder('c');
$qb->select('c')
->innerJoin('c.phones', 'p', Join::ON, $qb->expr()->andx(
$qb->expr()->eq('p.customerId', 'c.id'),
$qb->expr()->eq('p.phone', ':phone')
))
->where('c.username = :username');
// $qb->select('c')
// ->innerJoin('c.phones', 'p')
// ->where('c.username = :username')
// ->andWhere('p.phone = :phone');
$qb->setParameters(array(
'username' => $username,
'phone' => $phone->getPhone(),
));
$query = $qb->getQuery();
return $query->getResult();
}
}
Je vais répondre à ma propre question.
Par conséquent, ce qui suit fonctionne pour moi
$qb->select('c')
->innerJoin('c.phones', 'p', 'WITH', 'p.phone = :phone')
->where('c.username = :username');
ou
$qb->select('c')
->innerJoin('c.phones', 'p', Join::WITH, $qb->expr()->eq('p.phone', ':phone'))
->where('c.username = :username');
Vous pouvez explicitement avoir une jointure comme ceci:
$qb->innerJoin('c.phones', 'p', Join::ON, 'c.id = p.customerId');
Mais vous devez utiliser l'espace de noms de la classe Join from doctrine:
use Doctrine\ORM\Query\Expr\Join;
Ou si vous préférez comme ça:
$qb->innerJoin('c.phones', 'p', Doctrine\ORM\Query\Expr\Join::ON, 'c.id = p.customerId');
Sinon, Join class ne sera pas détecté et votre script se bloquera ...
Voici le constructeur de la méthode innerJoin:
public function innerJoin($join, $alias, $conditionType = null, $condition = null);
Vous pouvez trouver d'autres possibilités (non seulement rejoindre "ON", mais aussi "WITH", etc ...) ici: http://docs.doctrine-project.org/fr/2.0.x/reference/ query-builder.html # la-classe-expr
[~ # ~] éditer [~ # ~]
Je pense que cela devrait être:
$qb->select('c')
->innerJoin('c.phones', 'p', Join::ON, 'c.id = p.customerId')
->where('c.username = :username')
->andWhere('p.phone = :phone');
$qb->setParameters(array(
'username' => $username,
'phone' => $phone->getPhone(),
));
Sinon, je pense que vous faites un mélange de ON et de, peut-être le problème.