IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Doctrine2 PHP Discussion :

Problème avec la QueryBuilder sur table avec UniqueConstraint sur 2 clés


Sujet :

Doctrine2 PHP

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2003
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 125
    Points : 55
    Points
    55
    Par défaut Problème avec la QueryBuilder sur table avec UniqueConstraint sur 2 clés
    J'essaie de récupérer les donées de plusieurs tables pour faire un json, mais je suis bloqué pour la jointure sur la table ayant une UniqueConstraint sur 2 clés.

    Pour l'instant j'en suis là (je récupère biens les éléments) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $qb = $this->_em->createQueryBuilder()
        ->select('partial s.{id, activity}, partial a.{id, title}, partial p.{id, evaluationType}')
        ->from('Innova\PathBundle\Entity\Step', 's')
        ->leftJoin('s.activity', 'a')    //jointure sur l'entité Activity
        ->leftJoin('a.parameters', 'p')  // jointure sur l'entité ActivityParameters
        ->andWhere('s.path = 2')
    ;
    mais je veux aussi joindre sur l'entité Evaluation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    /**
     * @ORM\Table(
     *     name="claro_activity_evaluation",
     *     uniqueConstraints={
     *         @ORM\UniqueConstraint(
     *             name="user_activity_unique_evaluation",
     *             columns={"user_id", "activity_parameters_id"}
     *         )
     *     }
     * )
     */
    class Evaluation
    {
        /**
         * @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\User")
         * @ORM\JoinColumn(onDelete="CASCADE", nullable=false)
         */
        protected $user;
     
        /**
         * @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\Activity\ActivityParameters")
         * @ORM\JoinColumn(name="activity_parameters_id", onDelete="CASCADE", nullable=false)
         */
        protected $activityParameters;
     
        /**
         * @ORM\Column(name="attempts_count", type="integer", nullable=true)
         */
        protected $attemptsCount;
     
    }
    Voilà l'entité User :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    /**
     * @ORM\Table(name="claro_user")
     * @ORM\Entity(repositoryClass="Claroline\CoreBundle\Repository\UserRepository")
     */
    class User 
    {
        /**
         * @var integer
         *
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
     
        /**
         * @var string
         *
         * @ORM\Column(name="first_name", length=50)
         * @Assert\NotBlank()
         */
        protected $firstName;
     
    }
    Voilà l'entité ActivityParameters

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    /**
     * @ORM\Entity
     * @ORM\Table(name="claro_activity_parameters")
     */
    class ActivityParameters
    {
        /**
         * @var integer
         *
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
     
        /**
         * @var \Claroline\CoreBundle\Entity\Resource\Activity
         *
         * @ORM\OneToOne(
         *     targetEntity="Claroline\CoreBundle\Entity\Resource\Activity",
         *     mappedBy="parameters"
         * )
         * @ORM\JoinColumn(name="activity_id", onDelete="CASCADE", nullable=true)
         */
        protected $activity;
     
        /**
         * @var string
         *
         * @ORM\Column(name="evaluation_type", nullable=true)
         */
        protected $evaluationType;
     
        /**
         * @return string
         */
        public function getEvaluationType()
        {
            return $this->evaluationType;
        }
    }
    Voilà l'entité Activity

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /**
     * @ORM\Table(name="claro_activity")
     */
    class Activity
    {
        /**
         * @var string
         * @ORM\Column(length=255, nullable=true)
         */
        protected $title;
     
        /**
         * @ORM\OneToOne(
         *     targetEntity="Claroline\CoreBundle\Entity\Activity\ActivityParameters",
         *     inversedBy="activity",
         *     cascade={"persist"}
         * )
         * @ORM\JoinColumn(name="parameters_id", onDelete="cascade", nullable=true)
         */
        protected $parameters;
     
        /**
         * @return string
         */
        public function getTitle()
        {
            return $this->title;
        }
    }
    Je ne vois pas comment modifier cette querybuilder pour récupérer les données de Evaluation. Je souhaiterais quelque chose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $qb = $this->_em->createQueryBuilder()
        ->select('partial s.{id, activity}, partial a.{id, title}, partial p.{id, evaluationType}, e')
        ->from('Innova\PathBundle\Entity\Step', 's')
        ->leftJoin('s.activity', 'a')   
        ->leftJoin('a.parameters', 'p')  
        ->andWhere('s.path = 2')
        ->leftJoin('je-ne-sais-pas-quoi', 'e')  <<====
        ->andWhere('e.user = 3')      //données pour un utilisateur spécifique
    ;
    Merci d'avance pour les idées, suggestion

  2. #2
    Membre régulier Avatar de Fahelis
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2014
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2014
    Messages : 77
    Points : 87
    Points
    87
    Par défaut
    Salut,
    Il me semble curieux que ton entité Evaluation ne soit liée à aucune autre entité (ou alors j'ai pas les yeux en face des trous, on est lundi matin )
    Du coup tu ne vas pas pouvoir faire une jointure sans lien avec ce que tu récupères déjà.
    Mais avec un lien entre evalution et une entre entité tu devrais pouvoir faire un truc comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $qb = $this->_em->createQueryBuilder()
        ->select('partial s.{id, activity}, partial a.{id, title}, partial p.{id, evaluationType}, e')
        ->from('Innova\PathBundle\Entity\Step', 's')
        ->leftJoin('s.activity', 'a')   
        ->leftJoin('a.parameters', 'p')
        ->leftJoin('x.attribut_lié', 'e')  // avec x = à 's', 'a' ou 'p' selon quelle entité tu lie à evaluation
        ->andWhere('s.path = 2')   // Pourquoi "andWhere" ici alors que c'est ton premier "where" ? ;) (enfin détail ça, si ça fonctionne :P)
        ->andWhere('e.user = 3')      //données pour un utilisateur spécifique
    Pensez au bouton quand votre problème est réglé afin de ne pas faire perdre leur temps aux gens qui essayent gentiment d'aider les autres

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Décembre 2003
    Messages
    125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2003
    Messages : 125
    Points : 55
    Points
    55
    Par défaut
    En fait Evaluation est lié à User et ActivityParameter par une clé multiple.

    j'ai "presque" trouvé la solution, en faisant une sous-requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    $qb->select('e, partial p.{id, evaluationType}, partial a.{id, title}')
        ->from('Claroline\CoreBundle\Entity\Activity\Evaluation', 'e')
        ->leftJoin('e.activityParameters', 'p')
        ->leftJoin('p.activity', 'a')
        ->where(
            $qb->expr()->in(    
                'a.id',
                $subq->select('a2.id')
                    ->from('Innova\PathBundle\Entity\Step', 's')
                    ->leftJoin(
                        's.activity',
                        'a2',
                        \Doctrine\ORM\Query\Expr\Join::WITH,
                        $subq->expr()->eq('s.path', '?1')   
                    )
                    ->getDQL()      
            )
        )
        ->andWhere($qb->expr()->eq('e.user', '?2'))
        ->setParameter(1, $pid)
        ->setParameter(2, $uid)
    ;
    Il me manque juste l'id du step dans les résultats. Si j'ajoute l'entité au select principal, j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Error: 's' is used outside the scope of its declaration.
    (ce qui en soit ne me choque pas...)

Discussions similaires

  1. [2008R2] Problème d'insertion sur table avec une unique colonne identity
    Par Kropernic dans le forum Développement
    Réponses: 12
    Dernier message: 04/10/2013, 08h16
  2. Faire un save sur table avec id s'incrémentant
    Par lili2704 dans le forum Hibernate
    Réponses: 2
    Dernier message: 16/03/2007, 17h23
  3. lenteur sur table avec beaucoup de colonne
    Par ukanoldai dans le forum Oracle
    Réponses: 3
    Dernier message: 23/01/2007, 13h36
  4. Insert avec select sur table avec Trigger d'insertion
    Par bran_noz dans le forum Développement
    Réponses: 5
    Dernier message: 23/12/2005, 14h38
  5. Requete sur table avec Tableau
    Par Sichagadel dans le forum Langage SQL
    Réponses: 3
    Dernier message: 08/11/2005, 14h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo