假设我有一个具有ManyToOne关系(带有EXTRA_LAZY)的实体,显然还有一个连接列。
eg. Article (main entity) -> Author (external entity)
假设我在文章中添加了一个没有映射到ORM的字段author_name
,并且在某些上下文中,该字段应该包含article->author->name
值(通常可以保持为空)。
当我查询一个文章列表时,我希望自动填充文章-author_name,而不实现对查询结果的每个元素执行select的getter。我希望Doctrine通过在原始查询中使用一个简单的连接来获取和水合该值……
我不想将抓取模式设置为渴望性能,因为在我的项目中,作者是一个非常复杂的实体。
这个是可能的吗?
谢谢
发布于 2017-03-13 07:21:17
也许我已经找到了一个解决方案。我不知道这是不是最好的方法,但它是有效的。
我已经在主类中添加了一个字段getter
public getAuthorName() {
return $this->author->name
}
在我的上下文中,这个getter只会在某些情况下被序列化程序调用。
在我的存储库代码中,我有一个特殊的方法(我对它进行了重构,以便任何方法都可以隐式调用它),以便在查询时强制填充文章->作者字段。该方法只需使用查询构建器将左连接添加到Author类,并将FetchMode临时设置为EAGER on文章->author。
最后,一个简单的存储库方法可能如下所示
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();
}
缺点是您必须定制每个查询,或者更好地为存储库的每个方法使用DQL / SQL / QueryBuilder,但是通过良好的重构,对于简单的包含情况,您可以编写一个基于field_name数组的通用方法来注入联接。
希望这对你有所帮助,如果你找到更好的方法,请添加你的答案。
PS。我写了上面的代码,因为我现在不在我的笔记本上,希望它在第一次执行时就能工作。
https://stackoverflow.com/questions/42551664
复制相似问题