Symfony/Doctrine 实体中的关系 COUNT
Symfony/Doctrine relation COUNT in entity
如标题所述,
我想 运行 1 个查询从 table 中获取结果以及它们各自关系的计数。
假设我有一个 Person
实体与 Friend
实体
有 OneToMany 关系
Person 实体可能如下所示:
class Person
{
/**
* @ORM\OneToMany(...)
*/
protected $friends;
public function __construct()
{
$this->friends = new ArrayCollection();
}
...
}
我想要实现的目标的经典 SQL 解决方案可能如下所示:
SELECT p.*, COUNT(f.id) as friendsCount
FROM Persons p
LEFT JOIN Friends f
ON f.person_id = p.id
GROUP BY p.id
现在我想知道这是否也可以在 DQL 中完成并将 count 值存储到 Person
实体
假设我扩展 Person
实体,例如:(请记住,这只是一个想法)
class Person
{
/**
* @ORM\OneToMany(...)
*/
protected $friends;
protected $friendsCount;
public method __construct()
{
$this->friends = new ArrayCollection();
}
...
public function getFriendsCount()
{
return $this->friendsCount;
}
}
现在我无法找到如何从 DQL 填充实体中的计数值:
SELECT p, /* What comes here ? */
FROM AppBundle\Entity\Person p
LEFT JOIN p.friends f
GROUP BY p.id
PS:我知道我可以做到:
$person->getFriends()->count();
甚至将其标记为 extra lazy 以获取计数结果。
虽然这个 count relationships 示例很好地展示了我正在尝试做的事情。
(从 dql 填充实体的非 @ORM\Column
属性)
Doctrine 可以吗?
这是否违反了一些稳固的原则? (建议零售价?)
Cookie 表达您的想法 ;)
您可能只想 select 根据需要进行计数,如上文 $person->getFriends()->count();
所述。但是,您可以同时 select 一个对象和一个计数(请参阅这些 Doctrine query examples),其中一个与您正在做的非常相似:
SELECT p, COUNT(p.friends)
FROM AppBundle\Entity\Person p
LEFT JOIN p.friends f
GROUP BY p.id
应该返回的是包含对象和计数的数组数组,如下所示:
[
[Person, int],
[Person, int],
...,
]
你最好的选择是在你的 PersonRepository
上调用存储库,类似于 findPersonsWithFriendCount()
,它看起来像:
public function findPersonsWithFriendCount()
{
$persons = array();
$query = $this->_em->createQuery('
SELECT p, COUNT(p.friends)
FROM AppBundle\Entity\Person p
LEFT JOIN p.friends f
GROUP BY p.id
');
$results = $query->getResult();
foreach ($results as $result) {
$person = $result[0];
$person->setFriendsCount($result[1]);
$persons[] = $person;
}
return $persons;
}
请记住,您需要在 Person
对象上添加一个 setFriendsCount()
函数。您还可以编写原生 SQL 查询并使用 result set mapping 自动将原始结果的列映射到您的实体字段。
如标题所述,
我想 运行 1 个查询从 table 中获取结果以及它们各自关系的计数。
假设我有一个 Person
实体与 Friend
实体
Person 实体可能如下所示:
class Person
{
/**
* @ORM\OneToMany(...)
*/
protected $friends;
public function __construct()
{
$this->friends = new ArrayCollection();
}
...
}
我想要实现的目标的经典 SQL 解决方案可能如下所示:
SELECT p.*, COUNT(f.id) as friendsCount
FROM Persons p
LEFT JOIN Friends f
ON f.person_id = p.id
GROUP BY p.id
现在我想知道这是否也可以在 DQL 中完成并将 count 值存储到 Person
实体
假设我扩展 Person
实体,例如:(请记住,这只是一个想法)
class Person
{
/**
* @ORM\OneToMany(...)
*/
protected $friends;
protected $friendsCount;
public method __construct()
{
$this->friends = new ArrayCollection();
}
...
public function getFriendsCount()
{
return $this->friendsCount;
}
}
现在我无法找到如何从 DQL 填充实体中的计数值:
SELECT p, /* What comes here ? */
FROM AppBundle\Entity\Person p
LEFT JOIN p.friends f
GROUP BY p.id
PS:我知道我可以做到:
$person->getFriends()->count();
甚至将其标记为 extra lazy 以获取计数结果。
虽然这个 count relationships 示例很好地展示了我正在尝试做的事情。
(从 dql 填充实体的非 @ORM\Column
属性)
Doctrine 可以吗?
这是否违反了一些稳固的原则? (建议零售价?)
Cookie 表达您的想法 ;)
您可能只想 select 根据需要进行计数,如上文 $person->getFriends()->count();
所述。但是,您可以同时 select 一个对象和一个计数(请参阅这些 Doctrine query examples),其中一个与您正在做的非常相似:
SELECT p, COUNT(p.friends)
FROM AppBundle\Entity\Person p
LEFT JOIN p.friends f
GROUP BY p.id
应该返回的是包含对象和计数的数组数组,如下所示:
[
[Person, int],
[Person, int],
...,
]
你最好的选择是在你的 PersonRepository
上调用存储库,类似于 findPersonsWithFriendCount()
,它看起来像:
public function findPersonsWithFriendCount()
{
$persons = array();
$query = $this->_em->createQuery('
SELECT p, COUNT(p.friends)
FROM AppBundle\Entity\Person p
LEFT JOIN p.friends f
GROUP BY p.id
');
$results = $query->getResult();
foreach ($results as $result) {
$person = $result[0];
$person->setFriendsCount($result[1]);
$persons[] = $person;
}
return $persons;
}
请记住,您需要在 Person
对象上添加一个 setFriendsCount()
函数。您还可以编写原生 SQL 查询并使用 result set mapping 自动将原始结果的列映射到您的实体字段。