RVa*_*een 5 entity count relationship symfony doctrine-orm
正如标题所述,
我想运行1个查询来从表中获取结果以及各自关系的计数.
假设我有一个Person与实体有OneToMany关系的Friend实体
Person实体可能如下所示:
class Person
{
/**
* @ORM\OneToMany(...)
*/
protected $friends;
public function __construct()
{
$this->friends = new ArrayCollection();
}
...
}
Run Code Online (Sandbox Code Playgroud)
我想要实现的经典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
Run Code Online (Sandbox Code Playgroud)
现在我想知道这是否也可以在DQL中完成并将计数值存储到Person实体中
可以说,我扩大了Person实体,如:(请记住,这只是一个想法)
class Person
{
/**
* @ORM\OneToMany(...)
*/
protected $friends;
protected $friendsCount;
public method __construct()
{
$this->friends = new ArrayCollection();
}
...
public function getFriendsCount()
{
return $this->friendsCount;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我无法找到如何从DQL填充实体中的计数值:
SELECT p, /* What comes here ? */
FROM AppBundle\Entity\Person p
LEFT JOIN p.friends f
GROUP BY p.id
Run Code Online (Sandbox Code Playgroud)
PS:我知道我可以这样做:
$person->getFriends()->count();
Run Code Online (Sandbox Code Playgroud)
甚至将它标记为额外的懒惰以获得计数结果.
我只是这个计算关系的例子很好地展示了我想要做的事情.
(这是@ORM\Column从dql 填充实体的非属性)
这可能与Doctrine有关吗?
这打破了一些坚实的原则吗?(SRP?)
饼干为你的虽然;)
您可能只想根据需要选择计数,如上所述$person->getFriends()->count();.但是,您可以同时选择对象和计数 - 请参阅这些Doctrine DQL示例,其中有一个与您正在执行的操作非常相似:
SELECT p, COUNT(p.friends)
FROM AppBundle\Entity\Person p
LEFT JOIN p.friends f
GROUP BY p.id
Run Code Online (Sandbox Code Playgroud)
应该返回的是带有对象和计数的数组数组,如下所示:
[
[Person, int],
[Person, int],
...,
]
Run Code Online (Sandbox Code Playgroud)
你最好的选择就是在你的电子邮件上进行调用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;
}
Run Code Online (Sandbox Code Playgroud)
请记住,您需要setFriendsCount()在Person对象上添加一个函数.您还可以编写本机SQL查询并使用结果集映射自动将原始结果列映射到实体字段.
| 归档时间: |
|
| 查看次数: |
4642 次 |
| 最近记录: |