Lug*_*ino 3 symfony doctrine-orm symfony-2.3
我正在尝试优化查询,因为我需要一个简单的列表作为一个附属于几个实体的实体.所以我创建了这个查询,你应该只给我一个id和名字:
public function findAllOrderByName() {
$qb = $this->createQueryBuilder('a');
$query = $qb->select(array('partial a.{id,name}'))
->addOrderBy('a.name', 'ASC')
->getQuery();
return $query->getResult();
}
Run Code Online (Sandbox Code Playgroud)
像这样在控制器中返回它:
public function getInstrumentsAction()
{
$instruments = $this->getDoctrine()->getRepository('AcmeInstrumentBundle:Instrument')->findAllOrderByName();
return array('instruments' => $instruments);
}
Run Code Online (Sandbox Code Playgroud)
而不仅仅是让我回到两个阵营,给我完整的对象,从而包括其他相关实体的所有领域.
它为什么不起作用?
它实际上完全按照设计工作.您观察的是您的相关实体的延迟加载.
首先添加:
echo $query->getSQL() . "\n";
return $query->getResult();
Run Code Online (Sandbox Code Playgroud)
你会看到类似的东西:
SELECT p0_.id AS id0, p0_.name AS name1 FROM instrument p0_ ORDER BY p0_.name ASC
Run Code Online (Sandbox Code Playgroud)
因此,只有您要求实际查询的两个字段.
echo sprintf("Instrument %s %s %s\n",
$instrument->getName(),$instrument->getSomeotherScalervalue());
Run Code Online (Sandbox Code Playgroud)
你会看到,虽然名称被回显,但是其他一些值甚至不在仪器表中.
就关系而言,让我们假设乐器与人有一种关系.
$persons = $instrument->getPersons();
Run Code Online (Sandbox Code Playgroud)
你会期望$ people是一个空数组,但它实际上是一个相当聪明的Doctrine\ORM\PersistentCollection.一旦你尝试用$ person做任何其他事情(即使是像count($ persons)那样简单的事情,也会触发另一个查询,并且所有链接的人物对象都将被加载.
这就是你所看到的.您实际上可以在logs/dev.log中查看查询.只要您拉入仪器,就只会生成一个查询.一旦你尝试用关系做某事,另一个查询就会消失.
解决问题
不要试图访问关系.
在访问关系之前,您可以执行$ persons-> setInitialized(true); 这将阻止加载.显然有点痛苦.
由于优化是您的目标,因此只返回一个数组结果.根本没有任何对象.
您也可以继续在查询中加入您的关系,但使用partial来引入相关实体的id.您的查询工作有点困难,但您不必担心会触发其他查询.
如果有一些方法可以在特定查询的基础上阻止延迟加载,那将会很好.但如果有,我一直无法找到它.