在实体集合上检索DISTINCT COUNT
的最佳实践是什么?
在此示例实体(Customer
)中,我与oneToMany
之间具有Orders
关系。
我想计算客户订购的销售和产品数量:
> select * from orders;
+----------+----------+----------+
| customer | sale_ref | prod_ref |
+----------+----------+----------+
| 1 | sale_1 | prod_1 |
| 1 | sale_1 | prod_2 |
| 1 | sale_2 | prod_1 |
| 1 | sale_3 | prod_3 |
+----------+----------+----------+
> select count(prod_ref) from order where customer = 1;
+-----------------+
| count(prod_ref) |
+-----------------+
| 4 |
+-----------------+
> select count(distinct(sale_ref)) from order where customer = 1;
+-----------------+
| count(prod_ref) |
+-----------------+
| 3 |
+-----------------+
这里是代码
use Doctrine\ORM\Mapping as ORM;
class Customer
{
/**
* @var \Doctrine\Common\Collections\Collection
* @ORM\OneToMany(targetEntity="Orders", mappedBy="customer", cascade={"persist", "remove"}, fetch="EXTRA_LAZY")
*/
protected $orders;
/**
* @return \Doctrine\Common\Collections\Collection
*/
public function getOrders(): \Doctrine\Common\Collections\Collection
{
return $this->orders;
}
/**
* @return int
*/
public function getOrdersProductCount(): int
{
return $this->orders->count();
}
}
class Orders
{
/**
* @var Customer $customer
* @ORM\ManyToOne(targetEntity="Customer", inversedBy="orders")
*/
protected $customer;
/**
* Non-unique sales reference
* @var string $salesRef
* @ORM\Column(name="sales_ref", type="string")
*/
protected $salesRef;
/**
* Unique product reference
* @var string $productRef
* @ORM\Column(name="product_ref", type="string")
*/
protected $productRef;
/**
* @return Customer
*/
public function getCustomer(): Customer
{
return $this->customer;
}
/**
* @return string
*/
public function getProductRef(): string
{
return $this->productRef;
}
/**
* @return string
*/
public function getSalesRef(): string
{
return $this->salesRef;
}
}
使用Customer->getOrdersProductCount()
可以很好地检索产品数量,并且被认为是“良好实践”,因为它不会在满载集合的情况下访问数据库:
https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/tutorials/extra-lazy-associations.html
如果将关联标记为额外的懒惰,则可以在不触发集合
Collection#count()
的全部负载的情况下调用集合的以下方法>但是,在此示例中,
Customer
可以有多个要销售的产品-salesRef
不唯一。检索DISTINCT COUNT
中salesRef
的最佳方法是什么?
可以/应该在实体存储库类中处理:
class OrdersRepository { public function getSalesCount($customer): int { return (int)$this->createQueryBuilder('o') ->select('COUNT(DISTINCT(o.salesRef))') ->where('o.customer = :customer') ->setParameter('customer', $customer) ->setMaxResults(1) ->getQuery() ->getSingleScalarResult(); } public function getProductCount($customer): int { return (int)$this->createQueryBuilder('o') ->select('COUNT(o.productRef)') ->where('o.customer = :customer') ->setParameter('customer', $customer) ->setMaxResults(1) ->getQuery() ->getSingleScalarResult(); } }
这有效,但是我需要加载entityManager / CustomerRepository才能访问这些方法,而至少我可以从实体内部检索产品计数...。
我如何才能从客户实体中访问不同的销售计数-如果有的话?
我已经考虑过使用Collection#filter()
方法和/或遍历Collection#filter()
实体来创建一个以Orders
作为键的数组,然后使用salesRef
,但这似乎并不“正确”-我怀疑我知道答案了(使用实体存储库
array_unique#count()
实体内部访问销售数量-最佳实践/方法是什么? 在实体集合上检索DISTINCT COUNT的最佳做法是什么?在此示例实体(客户)中,我与Orders具有oneToMany关系。我想计算多少销售&...
我认为这应该做到,并且将是一种更可移植的方式。我没有测试它。