Hello,

j'essaye de faire cette requête toute simple avec Doctrine :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
 
SELECT c.feature_id, COUNT(DISTINCT c.enable) AS cardinality_enable, c.enable, COUNT(DISTINCT m.id) AS cardinality_map
            FROM maps m
            JOIN map_capabilities mc
                ON (m.id=mc.map_id)
            JOIN capabilities c
                ON (mc.capability_id=c.id)
            WHERE m.id IN ( 1,2,3 )
            GROUP BY c.feature_id
J'ai essayé avec le query builder :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
 
$queryBuilder = $em->createQueryBuilder()
                ->select('IDENTITY(c.feature) AS feature_id, COUNT(DISTINCT c.enable) AS cardinality_enable, c.enable, COUNT(DISTINCT m.id) AS cardinality_map')
                ->from('Bundle:Capability', 'c')
                ->join('Bundle:Map', 'm')
                ->groupBy('c.feature');
                ;   
            $queryBuilder->where($queryBuilder->expr()->in('m.id', $whereList))
La query produite ne fait pas le bon lien entre la table map et capability.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
SELECT c0_.feature_id AS sclr_0, COUNT(DISTINCT c0_.enable) AS sclr_1, c0_.enable AS enable_2, COUNT(DISTINCT m1_.id) AS sclr_3 FROM capabilities c0_ INNER JOIN maps m1_ ON (m1_.id IN (1)) GROUP BY c0_.feature_id
On voit bien qu'il manque la table de relation map_capabilities . Je ne sais pas comment la spécifier dans le query_builder pour que ça fonctionne bien.


Dans mes entités, j'ai ça dans ma classe Map

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
/**
     * @var array $capabilities The map's capabilities.
     * @ORM\ManyToMany(targetEntity="Capability", cascade={"persist","remove"})
     * @ORM\JoinTable(
     *      name="map_capabilities",
     *      joinColumns={@ORM\JoinColumn(name="map_id", referencedColumnName="id", onDelete="CASCADE")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="capability_id",referencedColumnName="id", onDelete="CASCADE")}
     * )
     */
    protected $capabilities;
et ça dans ma classe Capability :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
 
/**
     * @var integer $id The id.
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

Comment puis-je faire ma jointure correctement ?

Sinon, je me suis demandé s'il n'était pas opportun de faire ce traitement en manipulant simplement les entités et en faisant des retraitements sur mon tableau PHP (COUNT(DISTINCT())) mais je trouve ça un peu dommage de ne pas pouvoir utiliser les fonctions de MySQL qui permettent de le faire simplement.
Quelle est la meilleure politique à adopter, car en utilisant le maniement direct d'entité, ça complexifie beaucoup le code PHP ? (alors qu'un ORM est là pour simplifier la tâche...) De plus, ça fait des tableaux de résultats beaucoup plus gros à stocker en mémoire et des perfs moins bonnes au final car on transfert + de données.


Merci!