web-dev-qa-db-fra.com

Symfony 2: INNER JOIN sur une table non liée avec doctrine générateur de requêtes

J'essaie de construire une requête avec le générateur de requête doctrine qui joint une table non liée comme celle-ci:

$query = $this->createQueryBuilder('gpr')
        ->select('gpr, p')
        ->innerJoin('TPost', 'p')
        ->where('gpr.contentId = p.contentId')

Mais ça ne marche pas. Je reçois toujours une erreur:

Erreur: la variable d'identification TPost utilisée dans l'expression du chemin de jointure mais n'a pas été définie auparavant.

J'ai recherché ce message d'erreur et tout le monde a répondu d'utiliser l'attribut alias + de la table comme p.someAttribute. Mais la table que je veux rejoindre n'est pas liée dans la table à partir de laquelle je commence ma sélection.

En tant que requête mysql normale, je l'écrirais comme ceci:

SELECT * FROM t_group_publication_rel gpr 
INNER JOIN t_post p 
WHERE gpr.content_id = p.content_id

Des idées sur ce que je fais mal?

29
serious.siriso

Aujourd'hui, je travaillais sur une tâche similaire et je me suis souvenu d'avoir ouvert ce problème. Je ne sais pas depuis quelle version doctrine cela fonctionne, mais en ce moment, vous pouvez facilement rejoindre les classes enfants dans le mappage d'héritage. Donc, une requête comme celle-ci fonctionne sans problème:

$query = $this->createQueryBuilder('c')
        ->select('c')
        ->leftJoin('MyBundleName:ChildOne', 'co', 'WITH', 'co.id = c.id')
        ->leftJoin('MyBundleName:ChildTwo', 'ct', 'WITH', 'ct.id = c.id')
        ->orderBy('c.createdAt', 'DESC')
        ->where('co.group = :group OR ct.group = :group')
        ->setParameter('group', $group)
        ->setMaxResults(20);

Je lance la requête dans ma classe parent qui utilise le mappage d'héritage. Dans mon post précédent, c'était un point de départ différent mais le même problème si je me souviens bien.

Parce que c'était un gros problème quand j'ai commencé ce problème, je pense que cela pourrait aussi être intéressant pour d'autres personnes qui ne le connaissent pas.

67
serious.siriso

Les jointures entre entités sans associations n'étaient pas possibles jusqu'à la version 2.4, où vous pouvez générer une jointure arbitraire avec la syntaxe suivante:

$query = $em->createQuery('SELECT u FROM User u JOIN Blacklist b WITH u.email = b.email');

Référence: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html

6
Yamir
$dql = "SELECT 
    a, md.fisrtName , md.LastName, mj
    FROM MembersBundle:Memberdata md
        INNER JOIN MembersBundle:Address a WITH md = a.empID
        INNER JOIN MembersBundle:Memberjob mj WITH md = mj.memberData
            ...
    WHERE
        a.dateOfChange IS NULL
    AND WHERE
        md.someField = 'SomeValue'";

return $em->createQuery( $dql )->getResult();
3
Jzapata

Une jointure DQL ne fonctionne que si une association est définie dans votre mappage. Dans votre cas, je dirais qu'il est beaucoup plus facile de faire une requête native et d'utiliser ResultSetMapping pour remplir vos objets.

0
Peter Kruithof