我创建了一个querybuilder
来将我想要的所有实体放到一个请求中,但最后,它发出了26个sql请求。
有办法吗?
感谢您的回复/帮助。
以下是查询构建器:
$builder = $this->createQueryBuilder("message")
->innerJoin("AppBundle:User", "user", "WITH", "message.sender = user.id")
->innerJoin("AppBundle:Thread", "thread", "WITH", "message.thread = thread.id")
->innerJoin("AppBundle:MessageMetadata", "messageMetadata", "WITH", "messageMetadata.message = message.id AND messageMetadata.participant != user.id")
;
$builder = $this->filterSoftdelete($builder, $user);
if($filters != null) {
foreach ($filters as $key => $value) {
$builder->andWhere("(message.recipient = :id AND user.firstname LIKE '%". $value ."%') OR
(message.recipient = :id AND user.lastname LIKE '%". $value ."%') OR
(message.recipient = :id AND thread.subject LIKE '%". $value ."%')")
->setParameter("id", $user->getId());;
}
} else {
$builder->andWhere("message.recipient = :id or message.sender = :id")
->setParameter("id", $user->getId());
}
if($ordering != null) {
foreach ($ordering as $key => $value) {
if($key == "subject") {
$builder->addOrderBy("thread.subject", $value);
} else if($key == "createdAt") {
$builder->addOrderBy("message." . $key, $value);
} else {
$builder->addOrderBy("messageMetadata.isRead", "desc");
}
}
} else {
$builder->addOrderBy("messageMetadata.isRead", "desc");
}
return $this->query($builder);
答案 0 :(得分:0)
您的构建器只应触发一个请求。但是,您可能正在尝试访问未获取的属性或已加入的集合,并且延迟加载会起作用,从而产生许多不需要的请求。
通常在控制器中,您可以使用构建器获取实体:
$entities = $em->getRepository('myrepo')->myCustomQuery($myparams...);
然后你遍历你的实体(也许在树枝上):
foreach ($entities as $entity) {
$entity->getAssociation()->doSomething; // sometime here you forgot to fetch sayed association
}
解决方案是在查询构建器中使用->addSelect()
,这将强制选择和保持关联实体。
基本上你在做:
SELECT entity.* FROM entity JOIN other_entity ON ...;
并且在需要的时候获取缺少的other_entity会导致不必要的查询。
但你应该这样做:
SELECT entity.*, other_entity.* FROM entity JOIN other_entity ON ...;
您应该使用symfony工具栏查看您的请求。
希望这有帮助