我正在使用Symfony2和Doctrine2。
有很多实例,当我有一个实体,我需要循环其关联的实体。当然,它经常触发新的查询,并且效率不高。
addselect
其他实体对现有实体是否有最佳做法?
想想你在symfony中使用paramconverter的时候。它只是让你成为实体。如果我检索订单并想要遍历其orderLines
怎么办?我是否需要构建新查询并retrieve->leftjoin('order.orderlines', 'l')->addselect('l')->where('order = $order')
?
答案 0 :(得分:1)
此情况下的最佳做法是使用显式连接关联实体的自定义存储库方法。然后,Doctrine将不必单独查询循环的每次迭代。您也可以在ParamConverter中使用此custom repository method。
这是一个示例控制器:
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/**
* @Route("/blog/{id}")
* @ParamConverter("post", class="MyBundle:Order",
options={"repository_method" = "findOrderWithLineItems"})
*/
public function showAction(Order $order)
{
}
然后在实体上指定自定义存储库:
namespace MyBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="MyBundle\Entity\OrderRepository")
*/
class Order
{
}
然后是您的自定义存储库:
namespace MyBundle\Entity;
use Doctrine\ORM\EntityRepository;
class OrderRepository extends EntityRepository
{
public function findOrderWithLineItems($id)
{
return $this->createQueryBuilder('o')
->join('o.orderLines', 'ol')
->where('o.id = :id')
->setParameter('id', $id)
->getQuery()
->getResult()
;
}
}
如果您希望总是获取关联实体(始终加入表),即使在基本实体上进行简单选择,您也可以在关联实体上指定一个热切联接: / p>
class Order
{
/**
* @ManyToOne(targetEntity="OrderLines", fetch="EAGER")
*/
private $orderLines;
}