Doctrine2 fetching rows that have manyToMany assoc

2019-07-06 23:53发布

问题:

everyone. I have 2 entities City and POI. Mapping looks like this:

class City {
/**
 * @ORM\ManyToMany(targetEntity="POI", mappedBy="cities")
 * @ORM\OrderBy({"position" = "ASC"})
 */
protected $pois;

and

class POI {
/**
 * @ORM\ManyToMany(targetEntity="City", inversedBy="pois")
 * @ORM\JoinTable(name="poi_cities")
 */
protected $cities;

I would like to fetch all POIs that have at least 1 association with some City using QueryBuilder. I should probably use exists() function but I don't quiet know how.

回答1:

You'd have to Left join them and check if cities is null.

$qb->select('p', 'c')
   ->from('AcmeDemoBundle:POI', 'p')
   ->leftJoin('p.cities', 'c')
   ->where('c IS NOT NULL');

I haven't tested it, but I hope it gives you the general direction. You can read more about the QueryBuilder from here.



回答2:

Docrine2 was changed in 2013, so the other solution displays error Error: Cannot add having condition on a non result variable. Now we cannot use joined alias just as a condition variable. We should use any of its properties like c.id

So you should fix the code to

$qb->select('p', 'c')
   ->from('AcmeDemoBundle:POI', 'p')
   ->leftJoin('p.cities', 'c')
   ->where('c.id IS NOT NULL');
$results = $qb->getQuery()->execute();

If you want to select entities that does not have any cities, use IS NULL.

$qb->leftJoin('p.cities', 'city')
    ->where('city.id IS NULL')
    ->getQuery()
    ->execute();

Description of a problem and link to the commit that responsible for that - http://www.doctrine-project.org/jira/browse/DDC-2780