给定user
和他的coupons
,我想获得一位用户及其所有优惠券:
foreach ($this->createQueryBuilder('x')->select('u, c')->where('x.email = ?0')->setParameter(0, $email)->leftJoin('u.coupons', 'c')->getQuery()->getResult() as $entity)
{
$entity->getCoupons();
}
这是非常好的,直到我忘记加入优惠券:
foreach ($this->createQueryBuilder('x')->select('u')->where('x.email = ?0')->setParameter(0, $email)->getQuery()->getResult() as $entity)
{
$entity->getCoupons();
}
遗憾的是,即使没有加入优惠券,这仍然有效。这里它做了另一个SELECT。另外,第二次选择将是错误的。我宁愿想要获得异常,也不想获得空数组。有没有解决方法呢?
答案 0 :(得分:2)
您正在经历的是预期的学说行为。
当您选择User
实体时,Doctrine将从数据库中获取记录。如果您未明确加入Coupon
实体(或与User
有关系的任何其他实体),则Doctrine将创建一个Proxy对象。通过调用$user->getCoupons()
访问此代理对象后,Doctrine将向数据库发出新查询以获取User
实体的优惠券。这称为lazy-loading
。
我不确定是否有办法以您描述的方式更改此内容。
您可以在名为UserRepository
的{{1}}中创建一个方法并在那里查询。每当您需要找到用户及其优惠券时,您只需使用以下命令在控制器中检索它:
findUserAndCoupons($email)
这样您就不需要记住实际的查询并将其复制/粘贴到所有地方。 :)