在Doctrine 2中获取关联实体字段的SUM的更好方法是什么?

时间:2011-06-02 07:39:47

标签: doctrine-orm

如何获取关联实体的字段总和?例如,Invoice和Bill分别具有OneToMany和ManyToOne关系,即Invoice可以有很多Bills。 Bill实体有一个Amount列。发票如何获得相关票据金额的总和?

3 个答案:

答案 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

此解决方案只能执行一个查询。