Symfony Doctrine2如何一对多获取=渴望的工作?

Symfony Doctrine2如何一对多获取=渴望的工作?,symfony,doctrine-orm,Symfony,Doctrine Orm,我使用的是symfony2.8/ORM2.5.2 我有两个实体,一个图库一个文件 我在文档中看到两件事 首先,现在OneToMany关系确实有fetch=EAGER选项。以前的版本中没有 其次,OneToMany似乎无法使用此每次查询获取方法的手动设置,但我不知道它是否是最新的,因为它指出: 在查询过程中更改获取模式仅适用于一对一 以及多对一关系 无论如何,我已经尝试了这两种方法,以下是我的疑问: public function findWithEager() { $qb = $this

我使用的是symfony2.8/ORM2.5.2

我有两个实体,一个图库一个文件

我在文档中看到两件事

首先,现在OneToMany关系确实有fetch=EAGER选项。以前的版本中没有

其次,OneToMany似乎无法使用此每次查询获取方法的手动设置,但我不知道它是否是最新的,因为它指出:

在查询过程中更改获取模式仅适用于一对一 以及多对一关系

无论如何,我已经尝试了这两种方法,以下是我的疑问:

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();
    }
}