Doctrine 2 DQL - 如何选择单向多对多查询的反面?

Gnu*_*fo1 20 php doctrine dql

我有两个类--Page和SiteVersion,它们有很多关系.只有SiteVersion知道这种关系(因为该站点是模块化的,我希望能够带走并放入SiteVersion所属的模块).

因此,我如何根据SiteVersion的标准选择页面?

例如,这不起作用:

SELECT p FROM SiteVersion v JOIN v.pages p WHERE v.id = 5 AND p.slug='index'
Run Code Online (Sandbox Code Playgroud)

我收到错误:

[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.
Run Code Online (Sandbox Code Playgroud)

即使我可以使用此查询选择"v".

我想我可以通过引入一个关系类(一个PageToVersion类)来解决这个问题,但有没有办法不这样做,或者让它双向化?

Ocr*_*ius 24

在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
    )
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用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
Run Code Online (Sandbox Code Playgroud)

1 = 1只是因为解析器的当前限制.

请注意,导致语义错误的限制是因为水合过程从所选实体的根开始.如果没有根,水化器就没有关于如何折叠fetch-joined或join结果的参考.

  • 不,体面的 SQL 规划器会在执行查询之前去除比较。 (2认同)

Imi*_*bas 0

我在这里找到了这个问题的可能解决方案。

根据该页面,您的查询应如下所示:

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

它能解决您的问题吗?