这是一个延续另一个主题的问题:
QueryBuilder/Doctrine 选择加入 groupby
请打开它,以便您可以看到数据库架构。
我的问题是:
我有一个目标,一个目标可以节省很多钱。
这意味着,如果您想为某个目标存钱,您将添加一些储蓄,因此储蓄通过 id 与目标相关联。
在那个主题中,有人谈到了储蓄和目标之间的单向链接,(我在储蓄表中有 goal_id,但在目标表中没有 saving_id)。
我想要做的是显示一个包含目标信息的表格,并在其中附加一个收集的值(不在数据库中),该值是与目标相关的所有节省值的总和:
例如:
Goals:
id: 1
goal name: Goal1
....
Savings:
id: 1
amount:10
goal_id: 1
id:2
amount:20
goal_id: 1
当我查询数据库时,我将得到一个包含目标信息的表和一个字段“收集的金额:在本例中为 30”。
我最初设法通过查询得到这个:
select
admin_goals.created,
admin_goals.description,
admin_goals.goal_date,
admin_goals.value,
admin_goals.budget_categ,
sum(admin_savings.value)
from admin_goals
inner join admin_savings on admin_savings.goal_id=admin_goals.id
where admin_goals.user_id=1
group by admin_goals.id
但是我想采用 symfony 方式,所以我使用查询生成器,创建了一个存储库,但没有得到相同的结果。
目标和储蓄之间的唯一链接是储蓄表中的 goal_id,这意味着使用查询生成器我必须从储蓄表开始..因为从目标表中我没有用于储蓄的外键。
但现在的问题是,因为我从储蓄表开始,当显示目标时,我得到一个空结果,那是因为最初没有目标的储蓄。
首先创建目标,然后创建节省。但是因为“储蓄”表中没有记录(我从)开始,所以我没有从“目标”表中得到任何内容,因为我在这两个表上有一个连接。
$qb = $this->createQueryBuilder('admin_savings');
$qb->select('SUM(admin_savings.value) AS savingValue')
->addSelect('admin_goals.id AS id')
->addSelect('admin_goals.created')
->addSelect('admin_goals.description')
->addSelect('admin_goals.goal_date')
->addSelect('admin_goals.value')
->addSelect('admin_budget.name') // daca vrei id atunci pune identity(admin_goals.categ_id) admin_budget.name, x.name
->join('admin_savings.goal_id', 'admin_goals', Join::WITH)
->join('admin_goals.budget_categ', 'admin_budget', Join::WITH) //parametru 2 e numele de referinta in selectul mare ex: admin_budget, putea fi x
->where($qb->expr()->eq('admin_goals.user_id', ':user'))
->groupBy('admin_goals.id')
->setParameter('user', $user);
我知道这是不可能的,所以我尝试了另一种方法,为什么我不正常查询目标实体,因为这就是我想看到的..
$repository = $this->getDoctrine()->getRepository('AppBundle:Goal');
$goals = $repository->findBy(array('user_id' => $userId));
我在 SavingsRepository 中创建了一个函数:
public function getSavingSumByGoal($goalId){
$qb = $this->createQueryBuilder('saving');
$qb->select('SUM(saving.value) AS savingValue')
->where($qb->expr()->eq('saving.goal_id', ':goal'))
->setParameter('goal', $goalId);
return $qb->getQuery()->getScalarResult();
}
所以现在我有了目标实体及其所有信息,但没有从储蓄中收集的金额,我需要以某种方式将其添加到我的 $goals 对象中。这是在我的控制器中
foreach($goals as $goal_item){
$savingSum=$SavingRepository->getSavingSumByGoal($goal_item->getId());
if($savingSum){
$goal_item->savingSum=$savingSum;
}else{
$goal_item->savingSum=0.00;
}
}
$goal_item->savingSum
是一个虚构的属性,它不存在于 $goal
对象中,我以此作为示例,我想以某种方式在 $goal
对象中插入 savingSum。
我不想在实体中创建另一个字段并进行设置,因为那样我就会在数据库中出现一个空列,而我不希望这样..我想保留表和实体的结构,并且仅添加目标表中目标的所有储蓄金额的总和。
但这不起作用。 我正在考虑在我的树枝中的 foreach 中以某种方式执行我的函数,但我认为这不是一个好主意。
{% for goal in goals %}
<tr style="">
<td>{{ goal.created|date('Y/m/d') }}</td>
<td>{{ goal.description|e }}</td>
<td>{{ goal.value|e }}</td>
<td>{{ goal.goal_date|date('Y/m/d') }}</td>
<td>{{ goal.name|e }}</td>
<td>{{ savingRepo->getSavingSumByGoal(goal.id)|e }} </td>
</td>
</tr>
{% endfor %}
这是一个不好的做法,它在 twig 中不起作用,但我知道人们在 Zend 和其他框架中使用了方法(在创建 foreach() 之后,你在当前对象(来自 foreach)id 上运行你的函数)基于此展示一些东西)
如果您对如何以 symfony 方式执行此操作有更好的想法..我总是可以运行 rawquery 并且它会起作用,但这不是我想要做的..必须有一种方法以 OOP 方式执行此操作..请帮忙。
谢谢!
我不想在实体中创建另一个字段并设置它,因为那样我就会在数据库中拥有一个空列
您不必将字段映射到数据库,它可以是普通的类字段