Лучший способ получить СУММУ поля связанного объекта в Doctrine 2?

Как я могу получить сумму полей связанного объекта? Например, Invoice и Bill имеют отношения OneToMany и ManyToOne соответственно, то есть Invoice может иметь много счетов. Сущность Bill имеет столбец Amount. Как счет-фактура может получить СУММУ соответствующей суммы счетов?


person Jeboy    schedule 02.06.2011    source источник


Ответы (3)


Вы просите «лучший способ», но неясно, какой метод вы используете сейчас?

Если вам не нужно оптимизировать, у меня будет метод в вашем классе объектов Invoice, например:

public function getTotal(){
    $total = 0;
    foreach($this->bills as $b){
        $total += $b->amount;
    } 
    return $total;
}

Он не особо оптимизирован, но красив и понятен.

Если вы решите, что вам нужно его оптимизировать, вы можете:

A) создайте некоторый класс обслуживания, который знает о entitymanager, у которого есть метод, такой как getInvoiceTotal(Entity\Invoice $invoice), который выполняет запрос DQL для извлечения SUM() из базы данных

or

B) Сохраняйте промежуточный итог как свойство счета-фактуры. Используйте обратные вызовы жизненного цикла для обновления суммы счета-фактуры при добавлении/удалении/обновлении счетов.

person timdev    schedule 03.06.2011

На странице Doctrine Сводные поля описывается мало возможных решений этой проблемы. Они похожи на то, что описал @timdev, но предоставляют больше деталей реализации и указывают на предостережения каждого из них.

person James Newell    schedule 23.04.2013

public function getTotal(){
$total = 0;
foreach($this->bills as $b){
    $total += $b->amount;
} 
return $total;
}

Лично мне не нравится вышеуказанное решение и доктрина агрегированное поле и подходит/оптимизируется, если вы ищете одну запись. Если вам нужно агрегировать несколько записей, как показано ниже:

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

С этим решением будет выполнен только один запрос.

person sonam    schedule 28.12.2015