向Symfony2实体添加功能

时间:2013-04-17 05:35:50

标签: symfony

我对如何向我的实体添加功能感到困惑。

说我有一张加费表。我的数据库表有这些字段

  • COMPANY_ID
  • 日期
  • 金额

我在Symfony2项目中创建了相应的FeeIncrease实体。

现在,对于我的应用程序的一部分,我需要显示一个HTML表,列出特定月份内发生的所有费用增长。该表将包含数据库表中的所有字段,但还将包含一个附加字段:先前的费用金额。像这样:

company_id | date       | amount | previous_amount
-----------+------------+--------+----------------
1          | 2013-02-03 | 500    | 400
3          | 2013-02-15 | 1000   | 800
8          | 2013-02-20 | 1100   | 500

从数据库的角度考虑,每一行都需要一个子查询,从表中选择最新的费用增加(即它查询当前增加日期之前的最新日期的费用增加)。

目前我正在使用Native SQL写出子查询,但业务逻辑的复杂性已经明确表明这不是一个长期的解决方案。不同的页面将需要不同的“where”子句,因此我将为每个页面编写新的查询。此外,还有更多的逻辑需要应用于字段本身,我更希望将此逻辑封装在其他对象中,而不是让它像我们现在一样在我的控制器和视图中浮动。

我的问题是,基本上,如何将依赖实体数据的额外属性添加到我的实体?

理想情况下,我会向$previousAmount实体添加FeeIncrease属性。 getPreviousAmount将是一种为我执行复杂查询的方法。但是,如何添加此方法并利用Doctrine的功能?例如,假设我使用->findAll()来获得一系列费用增加。然后,在我的模板中,我遍历数组,但是对于每次费用增加,我显示之前的数量:

{% for feeIncrease in feeIncreases %}
  {{ feeInrease.previousAmount }}
{% endfor %}

对于每次增加,这将导致另一个数据库调用。考虑到我想要显示的费用增加的数量,这在我的情况下将无法使用。

任何指针都会非常感激。

更新:

这是我正在谈论的一个例子。

我上面描述的费用增加与合同有关。每份合同都有很多费用增加。对于每个月,每份合同都有“当前”费用,可通过以下规则找到:

  • 如果合约从当月开始有新的费用增加,请使用该金额。
  • 如果合约在当月结束时加费,而不是另一个跟进,则使用该金额。

还有其他规则。所以我的问题是,我在哪里可以放置这些规则,这样当我实际使用contractfeeIncrease个对象时,我可以使用像contract.currentFee这样的方法,而无需添加所有这个逻辑在哪里?

1 个答案:

答案 0 :(得分:0)

您可以使用与您的实体耦合的repository:这样您就可以将所有sql(或DQL或查询构建器)保存在同一个位置,甚至可以对其进行参数化。
这种方法的一个优点是你甚至可以使用相同的查询获取 ALL DATA ,并将返回的值用于twig模板,而不需要对doctrine的延迟加载工具进行需求后续操作。

所以你将拥有像FeeIncrease

这样的实体
/**
* @ORM\Table(name="FeeIncrease")
* @ORM\Entity(repositoryClass="Company\BundleNameBundle\Repository\FeeIncreaseRepository")
*/

class FeeIncrease
{
  [...]
}

您指定存储库位置,然后以这种方式创建存储库

//Company\BundleNameBundle\Repository\FeeeIncreaseRepository
<?php

namespace Company\BundleNameBundle\Repository;

use Doctrine\ORM\EntityRepository;

/**
 * FeeIncreaseRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */

class FeeIncreaseRepository extends EntityRepository
{
  public function myCostumQuery($paramers)
  {
    //your own logic here
  }
}