Доктрина 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
Другие вопросы по тегам