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

2022-01-16 00:00:00 php doctrine dql

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

I have two classes - Page and SiteVersion, which have a many to many relationship. Only SiteVersion is aware of the relationship (because the site is modular and I want to be able to take away and drop in the module that SiteVersion belongs to).

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

How would I therefore select pages based on criteria of SiteVersion?

例如,这不起作用:

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

我得到错误:

[DoctrineORMQueryQueryException]
[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".

Even though I can select "v" with this query.

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

I think I could possibly resolve this by introducing a class for the relationship (a PageToVersion class) but is there any way without doing that, or making it bidirectional?

推荐答案

Doctrine ORM 中有两种处理方法.最典型的是使用带有子查询的 IN 条件:

There's two ways of handling this in Doctrine ORM. The most typical one is using an IN condition with a subquery:

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 只是因为解析器的当前限制.

The 1 = 1 is just because of a current limitation of the parser.

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

Please note that the limitation that causes the semantical error is because the hydration process starts from the root of the selected entities. Without a root in place, the hydrator has no reference on how to collapse fetch-joined or joined results.

相关文章