2017-03-02 45 views
2

假设我有一个具有ManyToOne关系(具有EXTRA_LAZY)的实体,显然是一个连接列。如何通过JOIN与Doctrine填充添加剂字段

eg. Article (main entity) -> Author (external entity) 

想我场author_name添加到没有映射到ORM而且在某些情况下本场应包含article->author->name值(通常它可以留空)的文章。

当我查询文章列表时,我想自动填充article-author_name,而无需实现对查询结果的每个元素执行select操作的getter。我希望Doctrine通过原始查询中的简单JOIN获取并保存该值...

我不希望将获取模式设置为性能,因为在我的项目中作者是一个非常复杂的实体。

这可能吗?

谢谢

+0

我今天检查了所有学说注释和还没有发现任何这样可以让你做到这一点。 –

回答

0

可能我找到了解决方案。不知道这是否是最好的方法,但它的工作原理。

我已经加入到主类中的字段的getter

public getAuthorName() { 
    return $this->author->name 
} 

在我的背景下,这个吸气只会在一定的条件下串行被调用。

在我的仓库代码,我有一种特殊的方法(即我重构,使任何方法可以隐含调用它)施以物品─>作者字段的人口查询时。该方法只需使用querybuilder将LEFT JOIN添加到Author类中,然后将FetchMode临时设置为Article-> author的EAGER。

在后面加上一个简单的存储库方法可能是这

public findAllWithCustomHydration() { 
    $qb = $this->createQueryBuilder('obj'); 
    $qb->leftJoin("obj.author", "a") 
     -> addSelect("a"); //add a left join and a select so the query automatically retrive all needed values to populate Article and Author entities 
    //you can chain left join for nested entities like the following 
    //->leftJoin("a.address", "a_address") 
    //-> addSelect("a_address"); 


    $q = $qb->getQuery() 
       ->setFetchMode(Article::class, "author", ClassMetadata::FETCH_EAGER); 
    //setFetchMode + EAGER tells Doctrine to prepopulate the entites NOW and not when the getter of $article->author is called. 
    //I don't think that line is strictly required because Doctrine could populate it at later time from the same query result or maybe doctrine automatically set the field as EAGER fetch when a LEFT JOIN is included in the query, but i've not yet tested my code without this line. 

    return $q->getResult(); 
} 

con是,你必须自定义每个查询或更好的使用DQL/SQL/QueryBuilder的用于回购的每一个方法,但具有良好的重构,对于简单的包含情况,您可以编写一个泛型方法,以field_name数组为基础注入该联接。

希望这个帮助,如果你找到一个更好的方法,添加你的答案。

PS。我已经写了上面的代码,因为现在我不在我的笔记本上,希望它能在第一次执行时运行。