我正在努力完成以下任务:
我有一个“Sprint”实体,它包含许多Ticket实体。 每个Ticket都有一个TicketStatus(另一个实体)。
现在,在渲染Sprint时,我想计算sprint的进度。
我在哪里以及如何做到这一点?
直观地说,我会将这个方法添加到我的Sprint实体(类似于getSprintProgress())。
但随后我不断阅读你不想在你的实体类中查询db,因为关注点已经分离了。
你会怎么做?
理想情况下,我会在db ...
上运行count()查询答案 0 :(得分:1)
这个问题有几种可行的方法。
首先,假设您已经在Sprint和Ticket实体之间定义了传统的Doctrine关联,那么您的Sprint :: getProgress()就可以了。门票将根据需要延迟加载。对于像这样简单的事情,这实际上是一个很好的起点。
通过定义查询并急切加载票证,您可以避免延迟加载(并且可能会获得一点性能提升)。如果您小心,可以优化查询,以便仅加载票证的所需部分(可能是状态字段)。并且可以避免完全加载已关闭的门票。
另一种方法是将进度计算器移动到它自己的类。所以你可能有一个SprintProgressCalculator :: calculate($ sprint)方法。将其定义为服务并注入数据库连接。对于渲染,您可以将计算器注入树枝扩展并创建自己的树枝功能。如果计算比简单查询更复杂,则可以采用这种方法。
最后,只是一般观察到ORM适用于基本的CRUD类型应用程序。与其参与更多面向业务的运营并没有多大关系。因此,如果您确实有更多涉及的计算器和业务逻辑,那么您可以考虑回退到简单的SQL。
答案 1 :(得分:0)
现在我已经在我的Sprint实体中实现了它。
public function getProgress() {
$tickets = $this->tickets;
$done_tickets = $tickets->filter(function(Ticket $ticket) {
return $ticket->getStatus()->getName() == 'Done';
})->count();
return ($done_tickets / $tickets->count()) * 100;
让我澄清一下我在这里做了什么:
$this->tickets
包含一个ArrayCollection。显然,ArrayCollections有一个名为filter的方法,它允许定义一个我可以随意做的闭包。 有关filter()方法的更多信息here
最后,我只计算完成门票的百分比与该冲刺中的门票总数。
这确实让我想知道两件事:
很想听到有关此事的其他意见。
干杯