gpt4 book ai didi

doctrine-orm - 教义 2 : Subquery alias creates an extra level in results

转载 作者:行者123 更新时间:2023-12-04 04:46:18 32 4
gpt4 key购买 nike

考虑以下 DQL:

SELECT
a,
(SELECT COUNT(c.id) FROM Comment c WHERE c.article_id = a.id) num_comments
FROM Article a

我希望结果包含所有文章列以及同一级别的 num_comments,但文章列被包装在索引 0 处的数组中:
array(
0 => array(
0 => array(
"id" => 1,
"title" => "Title",
),
"num_comments" => 15
),
1 => array(
0 => array(
"id" => 2,
"title" => "Title",
),
"num_comments" => 20
)
);

如何将所有文章列和任何额外字段保持在同一级别?

最佳答案

我将把我的答案分为简短解释和详细解释(以及替代答案)。

简短说明:

SELECT a.field1
, ...
, a.fieldN
, (SELECT COUNT(c.id) FROM Comment c WHERE c.article_id = a.id) num_comments
FROM Article a

然后将其作为 ARRAY 水合物,它会返回您所期望的。

长说明:

每当您引用实体本身(在您的情况下,“SELECT a”),这意味着您请求返回与任何其他元素隔离的整个实体。
默认情况下,Doctrine 总是将此实体分配给索引 0,并根据您选择的 FROM 实体的数量继续。要更改此行为,您只需为实体设置别名,就像您对子查询所做的一样:
SELECT a AS article
, (SELECT COUNT(c.id) FROM Comment c WHERE c.article_id = a.id) AS num_comments
FROM Article a

这将返回如下内容:
array(
0 => array(
"article" => array(
"id" => 1,
"title" => "Title",
),
"num_comments" => 15
),
1 => array(
"article" => array(
"id" => 2,
"title" => "Title",
),
"num_comments" => 20
)
);

如果您不希望返回整个实体,您可以使用 PARTIAL 支持并只返回您感兴趣的字段。让我们支持您只需要 id (强制性,因为它是实体标识符)和标题:
SELECT PARTIAL a.{id, title} AS article
, (SELECT COUNT(c.id) FROM Comment c WHERE c.article_id = a.id) AS num_comments
FROM Article a

另一种方法是将结果封装到 DTO 中。当您决定将水合物值作为对象时,这将提供更多的 OO 控制。 DQL 看起来像这样:
SELECT NEW ArticleDTO(a, COUNT(c.id)) 
FROM Article a
LEFT JOIN a.comments c
GROUP BY a.id

不能将整个子查询作为参数放置的原因是由于 DQL 的限制。没有人请求过完整的子查询,所以现在我们遵循 JPA 建议的 ScalarExpression。

干杯,

吉尔梅·布兰科

关于doctrine-orm - 教义 2 : Subquery alias creates an extra level in results,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18116627/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com