进一步研究:看起来答案取决于changin默认Hydrator的定制化。 Doctrine2允许您通过将其名称作为参数发送来更改它:
$查询 - >的getResult( 'CustomHydrator');
别忘了先在config.yml文件中注册它:
doctrine:
orm:
hydrators:
CustomHydrator: \your\bundle\Hydrators\CustomHydrator
在研究了如何在Doctrine 2中为获取的对象添加额外字段后,我找到了Aggregate Fields,这是一篇很好的文章,但只是谈论从一个帐户中获得平衡,它从不说出我们应该做什么在使用一系列帐户时,它可能听起来很傻但让我解释一下我的情况。
在我的情况下,不是关于帐户和条目,而是关于博客和评论。
我要做的是列出一些博客,只显示它有多少评论而不加载任何评论信息,换句话说我想将此查询翻译成Doctrine2世界。
'SELECT b.*, COUNT( b.id ) AS totalComments FROM `blogs` b LEFT JOIN comments c ON b.id = c.blog_id GROUP BY b.id LIMIT 8'
我期望的结果是博客对象数组,其中totalComments属性设置正确,如下所示:
array (size=8)
0 =>
object Blog
'id' => int 330
'title' => string 'title blog'
// Added field, not visible in table DB. Came through query COUNT() statement
'totalComments' => int 5
// ... more attributes
1 => ...
//more object blogs
);
我无法实现这一点,我能做的最好的就是:
创建和获取查询:
$qb = $this->createQueryBuilder('b')
->select('b, c')
->addSelect('count(b.id) as nComments')
->leftJoin('b.comments', 'c')
->groupBy('b.id')
return $qb->getQuery()->getResult();
我得到的结果是一个数组数组,其中位置0有博客对象和位置“totalComments”
// var_dump($result)
array (size=8)
0 =>
array(2) =>
0 =>
object Blog
'id' => int 330
'title' => string 'title blog'
// ... more attributes
"totalComments" => int 5
1 => ...
);
我也尝试制作自己的Hydrator,但我刚开始使用Doctrine2,发现自己有点迷失。
我希望已经足够清楚了。如果需要,我可以提供任何其他信息。
提前致谢!
答案 0 :(得分:1)
您必须为所需的字段命名,或者具有混合结果(如第二个示例)。所以对于平面阵列:
$qb = $this->createQueryBuilder('b')
->select('b.title, b.author')
->addSelect('count(c.id) as nComments')
->leftJoin('b.comments', 'c')
->groupBy('b.id')
return $qb->getQuery()->getArrayResult();
或混合结果:
$qb = $this->createQueryBuilder('b')
->select('b')
->addSelect('count(c.id) as nComments')
->leftJoin('b.comments', 'c')
->groupBy('b.id')
return $qb->getQuery()->getResult();
答案 1 :(得分:0)
几天后我想出了这个解决方案。
我必须在我的博客实体类及其get / set方法中添加totalComments
属性,并调整一下我的getLatestBlogs函数:
function getLatestBlogs(){
$qb = $this->createQueryBuilder('b')
->select('b, c')
->addSelect('count(b.id) as totalComments')
->leftJoin('b.comments', 'c')
->groupBy('b.id');
$result = $qb->getQuery()->getResult();
//tweaking original result
foreach($result as $row){
$row[0]->setTotalComments($row['totalComments']);
$blogList[] = $row[0];
}
return $blogList;
}
这样做我终于得到了一个简单的博客对象数组,它只需要额外的循环。
在此之后,我意识到拥有一个可以使用任何实体的通用函数会很好,所以我创建了下一个函数:
function fixResult($qResult){ //Receives $qb->getQuery()->getResult();
if(is_array($qResult)){
$list = array();
$keys = array_keys($qResult[0]); //Getting all array positions from first row
$object = $qResult[0][0]; //Getting the actual object fetched
foreach($keys as $key){ //Searching for existing set methods in the Object
$method = "set".ucfirst($key);
if(method_exists($object,$method))
$methods[$key] = $method;
}
foreach($qResult as $row){ //Calling set methods for every row fetched and storing into a new array
foreach($methods as $key => $met){
$row[0]->$met($row[$key]);
$list[] = $row[0];
}
}
return $list;
}
else return false;
}
我希望别人觉得它很有用。