如何获取关联实体的字段总和?例如,Invoice和Bill分别具有OneToMany和ManyToOne关系,即Invoice可以有很多Bills。 Bill实体有一个Amount列。发票如何获得相关票据金额的总和?
答案 0 :(得分:2)
你要求的是“更好的方式”,但目前尚不清楚你现在使用的是什么方法?
除非你需要优化,否则我的Invoice实体类中只有一个方法,如:
public function getTotal(){
$total = 0;
foreach($this->bills as $b){
$total += $b->amount;
}
return $total;
}
它没有特别优化,但它很好而且清晰。
如果您决定需要优化它,您可以:
A)创建一个了解entitymanager的服务类,它有一个像getInvoiceTotal(Entity \ Invoice $ invoice)这样的方法,它执行DQL查询以从数据库中获取SUM()
或
B)将运行总计作为Invoice的属性。使用生命周期回调更新添加/删除/更新帐单时的发票总额。
答案 1 :(得分:2)
Doctrine Aggregate Fields页面概述了此问题的一些可能解决方案。它们类似于@timdev描述的内容,但提供了更多的实现细节,并指出了各自的警告。
答案 2 :(得分:1)
public function getTotal(){
$total = 0;
foreach($this->bills as $b){
$total += $b->amount;
}
return $total;
}
就个人而言,我不喜欢上述解决方案和学说aggregate field solution,如果您正在寻找单个记录,那么它是合适/优化的。 如果您必须汇总多个记录,如下所示:
|---invoice_id----|---bill total---|
| 1 | 100 |
| 2 | 200 |
| 3 | 300 |
这将获取相关发票的所有相关账单。因此,对于n个发票记录,它将获取每个发票的所有相关发票,从而损害优化。
对于这种情况,我做了类似的事情:
<?php
class InvoiceDTO
{
public function __construct($id, $total)
{
// Bind values to the object properties.
$this->invoiceId=$id;
$this->total= $total;
}
}
$query = $em->createQuery('SELECT NEW InvoiceDTO(i.id,SUM(b.amount)) FROM Invoice i JOIN i.bill b GROUP BY i');
$users = $query->getResult(); // array of InvoiceDTO
此解决方案只能执行一个查询。