我使用的是doctrine2和symfony3.1
我有一个电影
列表,人们可以使用一对多关系购买门票
在仪表板上,我想显示电影列表,以及每部电影购买的门票数量
通过这样做我得到了我想要的数据
$manager = $this->getDoctrine()->getManager();
$builder = $manager->createQueryBuilder();
$results = $builder
->select('m')
->from('AppBundle:Movie', 'm')
->addSelect($builder->expr()->count('t'))
->leftJoin('m.tickets', 't')
->groupBy('m.id')
->getQuery()
->getResult()
;
它为 100 部电影、1 个请求制作:
SELECT
e0_.title AS title_0,
e0_.is_published AS is_published_1,
e0_.description AS description_2,
e0_.author AS author_3,
e0_.director AS director_4,
e0_.artist_list AS artist_list_5,
e0_.tags_list AS tags_list_6,
e0_.creation_time AS creation_time_7,
e0_.id AS id_8,
COUNT(t1_.id) AS sclr_9,
e0_.place_id AS place_id_10,
e0_.organization_id AS organization_id_11,
e0_.inner_image1_id AS inner_image1_id_12,
e0_.inner_image2_id AS inner_image2_id_13,
e0_.inner_image3_id AS inner_image3_id_14,
e0_.image_id AS image_id_15
FROM event e0_
LEFT JOIN event_occurence e2_ ON e0_.id = e2_.event_id
LEFT JOIN ticket t1_ ON e2_.id = t1_.occurence_id
WHERE e0_.organization_id = '956744cb-6f76-4328-8ea5-c9715d762509'
GROUP BY e0_.id
LIMIT 100;
这正是我想要的发出 SQL 请求的结果。
问题出在 ORM 方面,结果是这样组织的
[
[ movie, nbrTickets],
[ movie, nbrTickets],
[ movie, nbrTickets],
]
我想知道如何向 Doctrine 提供提示,以便 nbrTickets
直接成为 Movie
的属性(目前我必须自己迭代),同时仍然只做1 个 SQL 查询(我强烈强调,所以我不想在我的 twig 中执行 movie.tickets | length
答案应满足以下要求:
- 执行1且仅一个 SQL 查询( => 否则,当我的页面显示 100 部电影时,它将仅针对此发出 101 个查询)
- 允许直接从实体内部访问结果(=>否则如上所述,我已经有了一个可以检索我想要的数据的解决方案,我有兴趣使代码更多地遵循 ORM)<
- 不要检索太多数据。
“目前在学说上不可能”的答案也是可以接受的。
最佳答案
您需要正确的注释才能使电影和门票实体中的关系发挥作用。
电影实体:
* One user has Many tickets.
* @ORM\OneToMany(targetEntity="Ticket", mappedBy="user")
*/
private $tickets;
票证实体:
* Many tickets have One movie.
* @ORM\ManyToOne(targetEntity="movie", inversedBy="tickets")
* @ORM\JoinColumn(name="movie_id", referencedColumnName="id")
*/
private $movie;
对于关系,您需要在构造函数中定义一个数组集合
public function __construct() {
$this->tickets = new ArrayCollection();
}
您需要为 Movie 实体创建一个 getTickets 函数,如下所示:
* tickets
*
* @return arrayCollection
*/
public function getTickets()
{
return $this->tickets;
}
然后,您可以使用以下存储库调用检索电影:
$movies = $this->getDoctrine()
->getRepository('AppBundle:movies')
->findAll();
最后你取回了票:
$tickets = $movies[0]->getTickets()
然后你用以下方法来计算它们:
$tickets->count()
关于php - 教义2 : get count of one to many relation directly mapped in entity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41410163/