簡體   English   中英

Doctrine 2 DQL - 如何選擇單向多對多查詢的反面?

[英]Doctrine 2 DQL - how to select inverse side of unidirectional many-to-many query?

我有兩個類--Page和SiteVersion,它們有很多關系。 只有SiteVersion知道這種關系(因為該站點是模塊化的,我希望能夠帶走並放入SiteVersion所屬的模塊)。

因此,我如何根據SiteVersion的標准選擇頁面?

例如,這不起作用:

SELECT p FROM SiteVersion v JOIN v.pages p WHERE v.id = 5 AND p.slug='index'

我收到錯誤:

[Doctrine\ORM\Query\QueryException]
[Semantical Error] line 0, col -1 near 'SELECT p FROM': Error: Cannot select entity through identification variables without choosing at least one root entity alias.

即使我可以使用此查詢選擇“v”。

我想我可以通過引入一個關系類(一個PageToVersion類)來解決這個問題,但有沒有辦法不這樣做,或者讓它雙向化?

在Doctrine ORM中有兩種處理方法。 最典型的是使用具有子查詢的IN條件:

SELECT
    p
FROM
    SitePage p
WHERE
    p.id IN(
        SELECT
            p2.id
        FROM
            SiteVersion v
        JOIN
            v.pages p2
        WHERE
            v.id = :versionId
            AND
            p.slug = :slug
    )

另一種方法是使用ORM版本2.3中引入任意連接功能進行額外連接:

SELECT
    p
FROM
    SitePage p
JOIN
    SiteVersion v
WITH
    1 = 1
JOIN
    v.pages p2
WHERE
    p.id = p2.id
    AND
    v.id = :versionId
    AND
    p2.slug = :slug

1 = 1僅僅是因為解析器的當前限制。

請注意, 導致語義錯誤的限制是因為水合過程從所選實體的根開始。 如果沒有根,水化器就沒有關於如何折疊fetch-joined或join結果的參考。

我認為您還需要在查詢中選擇SiteVersion:

SELECT v, p FROM SiteVersion v JOIN v.pages p WHERE v.id = 5 AND p.slug='index'

您將獲得一組SiteVersion實體,您可以循環以獲取Page實體。

試試這個(或類似的東西):

SELECT p FROM Page p WHERE EXISTS (SELECT v FROM SiteVersion v WHERE p MEMBER OF v.pages AND v.id = 5 AND p.slug = 'index')

我沒有完全測試過這個,但是我得到了類似的東西。 EXISTSMEMBER OF的使用隱藏在DQL章節的DQL Select Examples部分中。

我無法弄清楚如何使本機查詢工作,所以已經以一種略微hacky的方式解決:

$id = $em->getConnection()->fetchColumn("SELECT
    pages.id
    FROM
    pages
    INNER JOIN siteversion_page ON siteversion_page.page_id = pages.id
    INNER JOIN siteversions ON siteversion_page.siteversion_id = siteversions.id
    WHERE siteversions.id = 1
    AND pages.slug = 'index'");

$page = $em->find('Page', $id);

我不喜歡它,因為它會導致對數據庫的更多查詢(特別是如果我需要獲取一個頁面數組而不是一個),但它可以工作。

編輯 :我決定去參加一個關聯課程。 現在我可以做這個查詢:

SELECT p FROM Page p, SiteVersionPageLink l
WHERE l.page = p AND l.siteVersion = 5 AND p.slug = 'index'

我發現這個問題的可能的解決方案在這里

根據該頁面,您的查詢應如下所示:

SELECT p FROM SiteVersion v, Page p WHERE v.id = 5 AND p.slug='index' AND v.page = p;

它能解決你的問題嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM