繁体   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