Symfony Doctrine2如何一对多获取=渴望的工作?
我使用的是symfony2.8/ORM2.5.2 我有两个实体,一个图库一个文件 我在文档中看到两件事 首先,现在OneToMany关系确实有fetch=EAGER选项。以前的版本中没有 其次,OneToMany似乎无法使用此每次查询获取方法的手动设置,但我不知道它是否是最新的,因为它指出: 在查询过程中更改获取模式仅适用于一对一 以及多对一关系 无论如何,我已经尝试了这两种方法,以下是我的疑问:Symfony Doctrine2如何一对多获取=渴望的工作?,symfony,doctrine-orm,Symfony,Doctrine Orm,我使用的是symfony2.8/ORM2.5.2 我有两个实体,一个图库一个文件 我在文档中看到两件事 首先,现在OneToMany关系确实有fetch=EAGER选项。以前的版本中没有 其次,OneToMany似乎无法使用此每次查询获取方法的手动设置,但我不知道它是否是最新的,因为它指出: 在查询过程中更改获取模式仅适用于一对一 以及多对一关系 无论如何,我已经尝试了这两种方法,以下是我的疑问: public function findWithEager() { $qb = $this
public function findWithEager()
{
$qb = $this->createQueryBuilder('g');
$query = $qb->getQuery();
$query->setFetchMode("CommonBundle\\Entity\\Gallery", "files", ClassMetadata::FETCH_EAGER);
return $query->getResult();
}
但当我这样做的时候:
foreach ($galleryRepository->findWithEager() as $gallery) {
foreach ($gallery->getFiles() as $file) {
$file->getId();
}
}
然后我得到了1+n个查询。第一个是SELECT*FROM Gallery,接下来的n个是SELECT*FROM File,其中id=:galleryId
我希望Doctrine执行1+1查询,第二个查询是从id所在的文件中选择*:GalleryListId
我错过什么了吗?这种行为是否在教义中实施
各国:
当使用fetch=EAGER标记一对多关联时,它现在将
比以前少执行一个查询,并在组合中正确工作
用indexBy
我们根本不清楚预期的行为是什么
欢迎有任何见解,谢谢 在PHP5.6上使用Orm2.5.6进行了大量搜索和测试后,我得到了一些结果 此时,不可能通过一次查询获取库实体,通过第二次查询获取所有相关文件实体 你有两个选择 使用左联接在一个查询中获取库和文件实体 这就是在注释上设置fetch=EAGER时->find*方法所做的。 您可以使用DQL手动执行此操作:从Gallery g LEFT JOIN g.f中选择g,f 同样,您不能在DQL查询上调用->setFetchMode'Gallery',files',ClassMetadata::FETCH_EAGER来获得相同的结果 。。。对于一对多关系,将fetch模式更改为eager将导致为每个加载的根实体执行一个查询。这与延迟获取模式相比没有任何改进,延迟获取模式也会在访问关联后逐个初始化关联 这将导致在第一次查询后立即运行n个附加查询,以获取库实体 通过一个查询获取库实体并延迟加载文件实体 这是Doctrine的默认行为fetch=LAZY,对于您访问的每一组Gallery$文件,将导致1个查询加上一个额外的查询,如果您访问所有这些文件,则会产生1+n个查询。 未来可能的选择 有一种方法可以实现您想要的功能,即通过一个查询获取库实体,然后通过第二个查询获取所有文件实体,但不幸的是,这种方法似乎没有太多效果 结论 如果您使用的是->find*方法,那么fetch=EAGER注释将得到尊重。条令将通过左连接来实现这一点。根据您的数据集,这可能是正常的,也可能是非常昂贵的 如果手动编写DQL或使用查询生成器,则必须保持一对多关系的联接,并记住将要获取的任何实体添加到select子句中
我的偏好是,只要您想要一对多的关系被急切地获取,我就编写DQL,因为它可以清楚地表明您的意图。您使用的是哪种版本的原则?应该是2.5。我使用的是doctrine orm v2.5.2。如果您使用queryBuilder检索对象,您应该使用leftJoin,而不是fetch策略:/n您是否也尝试过在文件上使用plain->findAll和循环?
foreach ($galleryRepository->findWithEager() as $gallery) {
foreach ($gallery->getFiles() as $file) {
$file->getId();
}
}