Doctrine 2 DQL - выберите строки, в которых поле "много ко многим" пуст?

У меня есть два класса в этом примере - DeliveryMethod и Country. Они имеют отношения "многие ко многим" друг с другом.

Что я хочу сделать, это выбрать все методы DeliveryMethods, у которых нет сопоставленных им стран.

Я могу сделать обратное, то есть выбрать все методы доставки, имеющие хотя бы одну страну -

SELECT m FROM DeliveryMethod m JOIN m.countries

Но я не могу понять, как это сделать, выберите, где поле стран пусто. В простом SQL я бы сделал следующее (deliverymethod_country - таблица ссылок):

SELECT m.* FROM deliverymethods m
LEFT JOIN deliverymethod_country dc ON dc.deliverymethod_id = m.id
WHERE dc.deliverymethod_id IS NULL

Однако любой эквивалент DQL этого не работает, например:

SELECT m FROM DeliveryMethod m LEFT JOIN m.countries WHERE m.countries IS NULL

Что дает мне эту ошибку:

[Syntax Error] line 0, col 75: Error: Expected end of string, got 'm'

Ответы

Ответ 1

Как насчет этого? Предполагая, что $qb является экземпляром построителя запросов

$qb->select('m')
   ->from('DeliveryMethods','m')
   ->leftJoin('m.countries','c')
   ->having('COUNT(c.id) = 0')
   ->groupBy('m.id');

Это даст вам методы DeliveryMethods, которые связаны со странами, и количество ассоциированных стран - 0

Ответ 2

Использовать Doctrine is empty

Он специально предназначен для проверки пустых ассоциаций:

$qb->select('m')->from('DeliveryMethods', 'm')->where('m.countries is empty')

Смотрите: Doctrine 2 ORM Documentation: Doctrine Query Language (поиск "пустой" )

Ответ 3

В объединениях и полях нет необходимости. Просто используйте функцию SIZE:

$qb->select('m')
   ->from('DeliveryMethods','m')
   ->where('SIZE(m.countries) = 0');

Это даст вам все методы без прикрепленных стран.

Ответ 4

Невозможно присоединиться к значениям NULL, IIRC. Извинения за опечатку на twitter, должны были сказать "не могу".