Доктрина DQL JOIN
У меня есть следующие сущности, сопоставленные с Доктриной 2:
class Zone
{
/**
* @ManyToOne(targetEntity="Zone", inversedBy="children")
* @var Zone
*/
protected $parent;
/**
* @OneToMany(targetEntity="Zone", mappedBy="parent")
* @var Zone[]
*/
protected $children;
/**
* @ManyToMany(targetEntity="Zone")
* @var Zone[]
*/
protected $descendants;
}
class Restaurant
{
/**
* @ManyToOne(targetEntity="Zone")
* @var Zone
*/
protected $zone;
}
В основном у Зоны есть родитель, а значит и дети. Поскольку дети могут иметь детей сами, каждая Зона также содержит список всех своих потомков.
Каждому ресторану назначена зона.
То, что я хочу сделать, это выполнить DQL JOIN, чтобы вернуть все рестораны в определенной зоне (включая всех ее потомков).
Если бы я должен был сделать это простым SQL, я бы написал:
SELECT r.* from Zone z
JOIN ZoneDescendant d ON d.zoneId = z.id
JOIN Restaurant r ON r.zoneId = d.descendantId
WHERE z.id = ?;
Можно ли сделать это с помощью Doctrine DQL, не добавляя $restaurants
собственности на Зону, и необходимость бесполезно усложнять модель предметной области?
2 ответа
Решение
Хорошо, я наконец нашел способ сделать это только с помощью JOIN (значительно быстрее в MySQL):
SELECT r
FROM Restaurant r,
Zone z
JOIN z.descendants d
WHERE r.zone = d
AND z = ?1;
Единственный способ сделать это в одном запросе DQL - использовать подзапрос:
SELECT r FROM Restaurant r WHERE r.zone IN (SELECT zc.id FROM r.zone z JOIN z.children zc WHERE z.id = :zoneId) OR r.zone = :zoneId