Doctrine : Pagination with left Joins

后端 未结 4 2098
长情又很酷
长情又很酷 2020-12-14 03:15

I would like to paginate a complex request with at least 2 left joins, but the pagination bundle I\'m using (KnpPaginationBundle) can\'t tell Doctrine how to count the resul

4条回答
  •  一整个雨季
    2020-12-14 04:01

    It is difficult to understand the entities in the original question, but I ran into this same problem and it was indeed solvable.

    Suppose that you have an entity like this:

      class User
      {
        // ...
        /**
         * @ORM\OneToMany(targetEntity="Registration", mappedBy="user")
         */
        private $registrations;
        // ...
      }
    

    The important thing is that it has a one-to-many relationship with another entity, and you want to be able to join to that via the QueryBuilder for whatever reason (for example, you may want to add a HAVING clause to your query to select only those entities with one or more of these other entities).

    Your original code might look like:

      $qb = $this->createQueryBuilder();
    
      $query = $qb
        ->select('u')
        ->add('from', '\YourBundle\ORM\Model\User u')
        ->leftJoin('\YourBundle\ORM\Model\Registration', 'r', 'WITH', 'u.id = r.user')
        ->groupBy('u.id')
        ->having($qb->expr()->gte($qb->expr()->count('u.registrations'), '1')
        ->getQuery();
    

    This will throw the exception: Cannot count query which selects two FROM components, cannot make distinction

    To fix this, rewrite the query so that the QueryBuilder only has one "from" component -- exactly as the exception indicates -- by moving the join inline. Like so:

      $qb = $this->createQueryBuilder();
    
      $query = $qb
        ->select('u')
        ->add('from', '\YourBundle\ORM\Model\User u LEFT JOIN u.registrations r')
        ->groupBy('u.id')
        ->having($qb->expr()->gte($qb->expr()->count('r'), '1')
        ->getQuery();
    

    Should work just fine with Doctrine's Paginator class, with no other bundles necessary. Also note the shorthand syntax on the join; with Doctrine you don't seen to specify the joined entity explicitly (although you can) since the mapping already knows what it is.

    Hope this helps somebody out, there isn't a lot on this issue out there. You can read more about how the internals handle this by looking at @halfer's comment here.

提交回复
热议问题