如何在Doctrine2 Symfony2上实现两个表交集

时间:2014-11-21 22:41:40

标签: symfony doctrine-orm

我对所有这些东西都很新,所以请原谅我的傻瓜。 我有两张桌子,客户和订单。 我需要在模板上显示所有客户的每个订单总金额。 根据MCV模型,我只希望控制器调用Clients存储库的方法,该方法返回一个数组,其中包含准备好将所有数据发送到模板的数据。 但是我在实现这个方面遇到了问题。 总而言之,我有:

实体: Clients.php:使用client.id Orders.php:与客户有很多关系,以及金额属性。

DefaultController.php

public function indexAction()
{
 $em = $this->getDoctrine()->getManager();
 $clientsWithTotals= $em->getRepository('ACMEAppBundle:Client')->getClientsWithTotals();
 return $this->render('ACMEAppBundle:Default:index.html.twig',$clientsWithTotals);
}

ClientRepository.php:

class ClientRepositoryextends EntityRepository
{
  public function getClientsWithTotals()
   {
             ???     
   }
}

index.html.twig

{% extends '::base.html.twig' %}
{% block content %}
<table>
<thead>
 <tr>
  <th>Id</th>
  <th>Total</th>
 </tr>
</thead>
<tbody>
 {% for entity in entities %}
  <tr>
   <td><{{ entity.id }}</td>
   <td>{{ entity.total }}</td>
  </tr>
 {% endfor %}
</tbody>
</table>
{% endblock %}

非常感谢

1 个答案:

答案 0 :(得分:0)

首先,模板使用的是一个尚未定义的变量(entities):

return $this->render(
    'ACMEAppBundle:Default:index.html.twig',
    array(
        'entities' => $clientsWithTotals
    )
);

实施存储库:

class ClientRepository extends EntityRepository
{
    public function getClientsWithTotals()
    {
        $this
            ->createQueryBuilder('client')
            ->join('client.orders', 'order');
    }
}

只要您从客户端到订单正确定义了oneToMany关联,并且$client->orders属性,join就会知道它必须仅过滤掉相关的订单与特定用户合作。

实施totals虚拟财产:

除非您执行以下操作之一,否则您的Client对象将无法知道总数是多少:

  1. 使用像SUM(orders.total) AS clientTotals这样的聚合函数从数据库中选择值。
  2. 从数据库中选择与客户关联的订单(Doctrine2将它们水合成$ client-&gt;订单),然后使用foreach循环来汇总所有值。
  3. 如上所述here


    <强>实施例。对于#1:

    您可以构建DQL查询,例如:

    SELECT
            client,
            SUM(orders.total) as clientTotal
        FROM ACMEAppBundle:Client AS client
        JOIN client.orders AS orders;
    

    上述查询通常会返回一个包含clients表中所有行的数组,格式如下:

    array(
        'client' => $client // an ACMEAppBundle:Client entity object
        'clientTotals' => $clientTotals // an integer value representing the aggregate sum
    );
    

    实现自定义水合器将允许您决定如何处理数据库查询返回的原始数组数据。

    <强>实施例。对于#2:

    class Client
    {
    
        ...
    
        public function getTotals()
        {
            $this->totals = 0;
            foreach ($this->getOrders as $order) {
                $this->totals += $order->getTotal();
            }
    
            return $clientTotals;
        }
    
        ...
    }