Доктрина DQL JOIN - PullRequest
       11

Доктрина DQL JOIN

3 голосов
/ 29 октября 2011

У меня есть следующие объекты, сопоставленные с Doctrine 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 в Zone и без необходимости бесполезно усложнять модель домена?

Ответы [ 2 ]

9 голосов
/ 30 октября 2011

Хорошо, я наконец нашел способ сделать это только с JOIN (значительно быстрее в MySQL):

SELECT r
FROM Restaurant r,
     Zone z
JOIN z.descendants d
WHERE r.zone = d
AND z = ?1;
1 голос
/ 30 октября 2011

Единственный способ сделать это в одном запросе 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
...