2017-09-25 5 views
0

J'ai fait un querybuilder pour obtenir toutes les entités que je veux en une requête mais à la fin, il fait 26 requêtes SQL.symfony querybuilder et l'augmentation du numéro de requête sql

Existe-t-il un moyen de le faire?

Merci pour toute réponse/aide.

Voici le constructeur de requête:

$builder = $this->createQueryBuilder("message") 
    ->innerJoin("AppBundle:User", "user", "WITH", "message.sender = user.id") 
    ->innerJoin("AppBundle:Thread", "thread", "WITH", "message.thread = thread.id") 
    ->innerJoin("AppBundle:MessageMetadata", "messageMetadata", "WITH", "messageMetadata.message = message.id AND messageMetadata.participant != user.id") 
; 

$builder = $this->filterSoftdelete($builder, $user); 

if($filters != null) { 
    foreach ($filters as $key => $value) { 
     $builder->andWhere("(message.recipient = :id AND user.firstname LIKE '%". $value ."%') OR 
       (message.recipient = :id AND user.lastname LIKE '%". $value ."%') OR 
       (message.recipient = :id AND thread.subject LIKE '%". $value ."%')") 
      ->setParameter("id", $user->getId());; 
    } 
} else { 
    $builder->andWhere("message.recipient = :id or message.sender = :id") 
     ->setParameter("id", $user->getId()); 
} 

if($ordering != null) { 
    foreach ($ordering as $key => $value) { 
     if($key == "subject") { 
      $builder->addOrderBy("thread.subject", $value); 
     } else if($key == "createdAt") { 
      $builder->addOrderBy("message." . $key, $value); 
     } else { 
      $builder->addOrderBy("messageMetadata.isRead", "desc"); 
     } 
    } 
} else { 
    $builder->addOrderBy("messageMetadata.isRead", "desc"); 
} 

return $this->query($builder); 

Répondre

0

Votre constructeur ne devrait feu d'une demande. Mais peut-être essayez-vous d'accéder à des collections attribut ou jointes qui ne sont pas récupérées et le chargement paresseux entre en jeu, créant ainsi de nombreuses requêtes indésirables.

En général, lorsque dans le contrôleur vous allez chercher vos entités en utilisant votre constructeur:

$entities = $em->getRepository('myrepo')->myCustomQuery($myparams...); 

Ensuite, on boucle vos entités (peut-être dans brindille):

foreach ($entities as $entity) { 
    $entity->getAssociation()->doSomething; // sometime here you forgot to fetch sayed association 
} 

La solution serait d'utiliser ->addSelect() dans votre générateur de requête, qui va forcer la sélection et l'hydratation des entités associées.

Fondamentalement, vous faites:

SELECT entity.* FROM entity JOIN other_entity ON ...; 

Et doctrine, en cas de besoin récupérer les other_entity manquantes résultant dans les requêtes indésirables.

Mais vous devriez faire:

SELECT entity.*, other_entity.* FROM entity JOIN other_entity ON ...; 

Vous devez utiliser la barre d'outils symfony pour regarder votre demande.

Hope this helps

+0

quand je le fais, j'ai un autre problème, comme, attendez une classe d'entité et gived une OtherEntity classe –

+0

dans votre constructeur $ = $ this-> createQueryBuilder ("message" -> innerJoin ("AppBundle: Utilisateur", "utilisateur", "WITH", "message.sender = user.id") -> innerJoin ("AppBundle: Thread", "thread", "WITH", " message.thread = thread.id ") -> innerJoin (" AppBundle: MessageMetadata "," messageMetadata "," AVEC "," messageMetadata.message = message.id ET messageMetadata.participant! = user.id ") ; vous pouvez ajouter $ builder-> addSelect ('user') ... –

+0

Merci, je vais l'essayer. Dans ce cas le innerjoin est ok mais dans d'autres cas dans mon projet, j'ai besoin d'un leftjoin parce qu'il y a des enregistrements où la clé étrangère est nulle. il n'y a aucun moyen de l'obtenir dans une demande avec le constructeur de requête? –