Doctrine 2 DQL - 如何选择单向多对多查询的反面? [英] Doctrine 2 DQL - how to select inverse side of unidirectional many-to-many query?

查看:81
本文介绍了Doctrine 2 DQL - 如何选择单向多对多查询的反面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个类 - 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] 
[语义错误]行0,col -1靠近'SELECT p FROM':错误:无法选择实体,而不选择至少一个根实体别名。

即使我可以使用此查询选择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 只是因为解析器的当前限制。



请注意,导致语义错误的限制是因为水合过程从所选实体的根开始。没有根本的地方,hydrator没有参考如何崩溃 fetch-joined 或加入的结果。


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).

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

For example, this doesn't work:

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

I get the error:

[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.

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

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?

解决方案

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
    )

The other way is with an additional join with the arbitrary join functionality introduced in version 2.3 of the ORM:

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

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.

这篇关于Doctrine 2 DQL - 如何选择单向多对多查询的反面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆