我想编写一个 DQL 查询来选择发布并加入另一个实体。
这是我的代码:
$dql = '
SELECT p , h ,t ,m
FROM App:Post p
LEFT JOIN p.mentions m
LEFT JOIN p.tags t
LEFT JOIN p.file h
WHERE p.user
IN (
SELECT f FROM App:User u
JOIN u.followers f
WHERE u.id = :uid
)
OR p.user = :uid ';
$query = $this->getEntityManager()
->createQuery($dql)
->setMaxResults(5)
->setParameters(['uid' => $user->getId()])
->getArrayResult();
但问题是setMaxResults
不限制帖子实体,而是限制 5 上的标签实体。
这是我的两种结果:
1.with setMaxResults(不能正常工作) https://jsoneditoronline.org/?id=71f2c51769504b5ca14d3c4624ef68a1
2.with setMaxResults(工作正常) https://jsoneditoronline.org/?id=aad5dc17594a46e7bbaed27eb5187bb5
我的代码有什么问题吗?
这是预期的行为在原则上使用时设置最大结果() or 设置第一个结果()没有分页器。
设置最大结果()实际上是添加一个SQL限制对于生成的查询,它不仅会像您期望的那样限制根实体,还会限制查询返回的行。这意味着在连接查询时它不会执行您想要的操作。
根据第一个和最大结果项 https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#first-and-max-result-items-dql-query-only
如果您的查询包含指定结果限制方法的 fetch-joined 集合,则该方法不会按您的预期工作。设置最大结果限制数据库结果行的数量,但是在提取连接集合的情况下,一个根实体可能会出现在许多行中,从而有效地混合少于指定数量的结果。
为了达到你想要的目的,你可以做的是使用分页器 https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/tutorials/pagination.html根据您的查询:
$query = $this->getEntityManager()
->createQuery($dql)
->setMaxResults(5)
->setParameters(['uid' => $user->getId()]);
$paginator = new Paginator($query, $fetchJoinCollection = true);
$c = count($paginator);
foreach ($paginator as $post) {
}
从上面的分页器文档链接:
对 Doctrine 查询进行分页并不像您一开始想象的那么简单。如果您有具有一对多或多对多关联的复杂 fetch-join 场景,则使用数据库供应商的“默认”LIMIT 功能不足以获得正确的结果。
另请注意:
默认情况下,分页扩展执行以下步骤来计算正确的结果:
- 使用执行计数查询
DISTINCT
关键词。
- 执行限制子查询
DISTINCT
查找当前页面中实体的所有 id。
- 执行 WHERE IN 查询以获取当前页面的所有结果。
仅当您实际获取连接到多对集合时,此行为才是必要的。您可以通过将 $fetchJoinCollection 标志设置为 false 来禁用此行为;在这种情况下,仅执行 2 个查询,而不是所描述的 3 个查询。我们希望将来能对此进行自动化检测。
类似问题 https://stackoverflow.com/questions/14884183/doctrine-querybuilder-limit-and-offset
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)