动态加载与 Doctrine 的深层关系

Posted

技术标签:

【中文标题】动态加载与 Doctrine 的深层关系【英文标题】:Dynamically eager loading deep relationships with Doctrine 【发布时间】:2016-05-27 15:32:51 【问题描述】:

我目前正在使用以下堆栈开发 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)而不是更深层次的关系(示例中的friends 中的addresses)。

谢谢!

【问题讨论】:

【参考方案1】:

如果我没记错的话,你可以通过加入它们来“预加载”关系,而不是让延迟加载机制来处理它。一个想法可能是创建一个根据您的条件创建查询构建器的服务。这是我的意思的粗略的sn-p:

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;
    

【讨论】:

谢谢,这似乎是最好的解决方案,所以我会在此基础上继续努力 很高兴我能帮上忙。我看到我忘了把 $str 改成 $includes 所以我修好了。 hm.. 最好为此创建一个包。

以上是关于动态加载与 Doctrine 的深层关系的主要内容,如果未能解决你的问题,请参考以下文章

如何动态加载外部CSS与JS文件

[转载] 动态链接库dll的 静态加载 与 动态加载

Symfony 4 - 加载动态用户角色的固定装置

角度 5 延迟加载与动态加载

Class.forName与动态加载

Java 类加载时机(动态静态) 与 类加载过程 详解