Symfony 实体存储库中的 Doctrine QueryBuilder 摘要函数?
Doctrine QueryBuilder summary functions in Symfony entity repositories?
有什么方法可以让我在 Doctrine 的 QueryBuilder 中使用 min()
(或等效的)?
我正在处理的页面显示了当前(或模拟)用户的 table 发票。他们的每张发票都有一行,并且有任何相关付款的嵌套可折叠行(见下图)
我的问题是,在我的 twig 模板中,如果任何付款尚未获得批准,我需要能够在发票级别进行识别。如果任何付款未获批准,那么我需要标记付款及其相关的发票行。例如,在下面的示例中,"Invoice #1" 是黄色的,因为它有一个嵌套的 "Payment #2" 记录是黄色的(未批准):
为了在发票级别访问它,我一直在尝试通过我的 InvoiceRepository 来完成它,但我不清楚 if/how 这可以使用 QueryBuilder 来完成。我不知何故需要 anyToBeApproved
(这不是我的发票实体的属性)可用,并且还包含付款信息:
select a.*, min(b.approved) as anyToBeApproved
from Invoice a
left join Payment b
on a.invoice_id=b.id
where a.member_id=$Uid
group by a.id
我的控制器:
$invoices = $em->getRepository('AppBundle:Invoice')->OutstandingForUser($this->getUser()->getId());
我的查询生成器:
public function OutstandingForUser($Uid)
{
return $this->createQueryBuilder('i')
->select('i')
->leftJoin('i.member_id','m')
->leftJoin('i.payment_ids','p')
->andwhere('m.member_id = :MemberId' )
->setParameter('MemberId',$Uid)
->getQuery()
->getResult();
}
我不知道为什么这个问题还没有得到解答,但你应该能够很好地使用这些聚合函数。
The following aggregate functions are allowed in SELECT and GROUP BY
clauses: AVG, COUNT, MIN, MAX, SUM
您可以在 querybuilder 中使用聚合函数 ->select() OK。
我会将您的函数重写为:
public function OutstandingForUser($Uid)
{
return $this->createQueryBuilder('i')
->select('i, min(p.approved) as anyToBeApproved')
->leftJoin('i.member','m', 'WITH', 'm.member_id = :MemberId') // this works better with not actually constraining your left join, otherwise you might as well just use innerJoin
->leftJoin('i.payment','p')
->groupBy('i.id')
->setParameter('MemberId',$Uid)
->getQuery()
->getResult();
}
这是另一种方法,因为您似乎无论如何都想要所有发票行。
将您的获取功能更改为:
public function OutstandingForUser($Uid)
{
return $this->createQueryBuilder('i')
->select('i, p, m') // may as well pre-fetch all entities
->join('i.member','m') // member is surely mandatory? so no left join required
->leftJoin('i.payment','p') // payments may not be present, so left join
->where('m.member_id = :MemberId')
->setParameter('MemberId',$Uid)
->getQuery()
->getResult();
}
然后在您的发票实体中执行类似
的操作
public function hasUnapprovedPayments () {
foreach ($this->getPayments() as $payment) {
if (!$payment->approved()) {
return true;
}
}
return false;
}
public function hasPayments () {
return !$this->getPayments()->isEmpty(); // assuming doctrine collection
}
这些函数会非常快,因为您已经在上面的函数中水化了实体。
您还可以添加一个类似的 isFullyPaid 方法来循环支付,但我个人会在发票完全支付时将其设置为布尔值或日期时间。
然后在 twig 中你可以做这样的事情:
{% for invoice in invoices %}
{% if invoice.hasUnapprovedPayments %} do something {% endif %}
{% if invoice.hasPayments %} do something {% endif %}
{# loop through all your payments etc #}
{% endfor %}
这应该可以很容易地获得您想要的布局。
有什么方法可以让我在 Doctrine 的 QueryBuilder 中使用 min()
(或等效的)?
我正在处理的页面显示了当前(或模拟)用户的 table 发票。他们的每张发票都有一行,并且有任何相关付款的嵌套可折叠行(见下图)
我的问题是,在我的 twig 模板中,如果任何付款尚未获得批准,我需要能够在发票级别进行识别。如果任何付款未获批准,那么我需要标记付款及其相关的发票行。例如,在下面的示例中,"Invoice #1" 是黄色的,因为它有一个嵌套的 "Payment #2" 记录是黄色的(未批准):
为了在发票级别访问它,我一直在尝试通过我的 InvoiceRepository 来完成它,但我不清楚 if/how 这可以使用 QueryBuilder 来完成。我不知何故需要 anyToBeApproved
(这不是我的发票实体的属性)可用,并且还包含付款信息:
select a.*, min(b.approved) as anyToBeApproved
from Invoice a
left join Payment b
on a.invoice_id=b.id
where a.member_id=$Uid
group by a.id
我的控制器:
$invoices = $em->getRepository('AppBundle:Invoice')->OutstandingForUser($this->getUser()->getId());
我的查询生成器:
public function OutstandingForUser($Uid)
{
return $this->createQueryBuilder('i')
->select('i')
->leftJoin('i.member_id','m')
->leftJoin('i.payment_ids','p')
->andwhere('m.member_id = :MemberId' )
->setParameter('MemberId',$Uid)
->getQuery()
->getResult();
}
我不知道为什么这个问题还没有得到解答,但你应该能够很好地使用这些聚合函数。
The following aggregate functions are allowed in SELECT and GROUP BY clauses: AVG, COUNT, MIN, MAX, SUM
您可以在 querybuilder 中使用聚合函数 ->select() OK。
我会将您的函数重写为:
public function OutstandingForUser($Uid)
{
return $this->createQueryBuilder('i')
->select('i, min(p.approved) as anyToBeApproved')
->leftJoin('i.member','m', 'WITH', 'm.member_id = :MemberId') // this works better with not actually constraining your left join, otherwise you might as well just use innerJoin
->leftJoin('i.payment','p')
->groupBy('i.id')
->setParameter('MemberId',$Uid)
->getQuery()
->getResult();
}
这是另一种方法,因为您似乎无论如何都想要所有发票行。
将您的获取功能更改为:
public function OutstandingForUser($Uid)
{
return $this->createQueryBuilder('i')
->select('i, p, m') // may as well pre-fetch all entities
->join('i.member','m') // member is surely mandatory? so no left join required
->leftJoin('i.payment','p') // payments may not be present, so left join
->where('m.member_id = :MemberId')
->setParameter('MemberId',$Uid)
->getQuery()
->getResult();
}
然后在您的发票实体中执行类似
的操作 public function hasUnapprovedPayments () {
foreach ($this->getPayments() as $payment) {
if (!$payment->approved()) {
return true;
}
}
return false;
}
public function hasPayments () {
return !$this->getPayments()->isEmpty(); // assuming doctrine collection
}
这些函数会非常快,因为您已经在上面的函数中水化了实体。
您还可以添加一个类似的 isFullyPaid 方法来循环支付,但我个人会在发票完全支付时将其设置为布尔值或日期时间。
然后在 twig 中你可以做这样的事情:
{% for invoice in invoices %}
{% if invoice.hasUnapprovedPayments %} do something {% endif %}
{% if invoice.hasPayments %} do something {% endif %}
{# loop through all your payments etc #}
{% endfor %}
这应该可以很容易地获得您想要的布局。