动态地渴望加载与Doctrine的深层关系

时间:2016-05-27 15:32:51

标签: symfony doctrine

我目前正在使用以下堆栈处理API;

  • Symfony(3)
  • FOSRestBundle
  • 分形

我想整合通过查询参数指定在检索实体/集合时要包含哪些关系的功能,例如

[GET] /users?include=friends.addresses
然而,

Fractal comes with the ability to handle includes因为这发生在响应构建的序列化点周围,所以通过延迟加载来检索每个相关实体,从而触发其他查询。

有没有办法在检索集合时告诉Doctrine动态地检索指定的关系?我见过the following from the Doctrine docs which shows how to dynamically change the fetch mode但是这似乎只适用于目标实体上的关联(上例中的friends)而不是更深层次的关系(示例中addresses的{​​{1}})

谢谢!

1 个答案:

答案 0 :(得分:2)

如果我没记错的话,你可以预先加载"通过加入它们而不是让延迟加载机制来处理它。一个想法可能是创建一个服务,根据您的标准创建一个查询生成器。这是我的意思的粗略片段:

class EagerService
{
    protected $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function resolveIncludes($class, $alias, $includes) 
    {
        // Parse includes into an array
        if (strpos($includes, '.') !== false) {
            $relations = explode('.', $includes);
        } else {
            $relations = [$includes];
        }

        // The next relation is owned by the previous one, so we keep track of the previous relation
        $previousRelation = $alias;
        $qb = $em->getRepository($class)->getQueryBuilder($previousRelation);
        foreach ($relations as $relation) {
            // Add inner joins to the query builder referencing the new relation
            $qb->innerJoin("{$previousRelation}.{$relation}", $relation);
            $previousRelation = $relation;
        }

        // Return query builder or the result of the query
        return $qb;
    }
}