Symfony 5 和 Doctrine,找不到使用 3 个相关实体获取结果的方法
Posted
技术标签:
【中文标题】Symfony 5 和 Doctrine,找不到使用 3 个相关实体获取结果的方法【英文标题】:Symfony 5 and Doctrine, can't find a way to fetch results with 3 related entities 【发布时间】:2021-03-04 06:49:08 【问题描述】:编辑:这个问题已经更新,我现在很好,感谢与@Jakumi 聊天。
我有多个网站在同一个 Symfony 5 安装上运行。 该网站根据视频类别显示视频,但它们共享相同的视频数据库。 我有一个名为“视频”、“网站”的实体,最后一个名为“类别”:
实体/视频.php
/**
* @ORM\ManyToMany(targetEntity=Category::class, inversedBy="videos")
* @ORM\OrderBy("priority" = "DESC")
*/
private $category;
实体/类别.php
/**
* @ORM\ManyToMany(targetEntity=Video::class, mappedBy="category")
*/
private $videos;
实体/Website.php
/**
* @ORM\ManyToMany(targetEntity=Category::class, inversedBy="websites")
*/
private $categories;
例如,我有 4 个视频及其类别。
video
id title
1 | "Lol Pro PLayer"
2 | "Lol Casual Player"
3 | "Counter Strike Casual Player"
4 | "Counter Strike Pro Player"
website
id | title
1 | "LOL PROS"
2 | "CS Gamers"
3 | "CS Pro Gamers"
category
id | title
1 | "Pro"
2 | "League of Legend"
3 | "Counter Strike"
video_category
video_id | category_id
1 | 1
1 | 2
2 | 2
3 | 3
4 | 1
4 | 3
website_category
website_id | category_id
1 | 1
1 | 2
2 | 3
3 | 1
3 | 2
目前,我能够获得这样的视频(肮脏的方式),我第一次硬编码了网站类别 ID。
网站 1 应该只显示属于“职业”和“英雄联盟”两个类别的视频(每个网站可以有 3 或 4 个类别),因此在他的示例中,只有名为“ Lol Pro Player" (id : 1)
App\Repository\VideoRepository.php
public function findWebsiteVideos($website)
$em = $this->getEntityManager();
return $query = $em->createQuery(
'SELECT v
FROM App\Entity\Video v
WHERE v.id IN(
SELECT DISTINCT v_1.id
FROM App\Entity\Video v_1
JOIN v_1.category vc_1
WHERE vc_1.id = 408
)
AND v.id IN(
SELECT DISTINCT v_2.id
FROM App\Entity\Video v_2
JOIN v_2.category vc_2
WHERE vc_2.id = 454
)
AND v.id IN(
SELECT DISTINCT v_3.id
FROM App\Entity\Video v_3
JOIN v_3.category vc_3
WHERE vc_3.id = 504
)
ORDER BY v.id ASC'
);
我正在尝试找到正确的 DQL 以避免脏活,我需要提一下,我不能在当前的分页系统中使用“HAVING”。
【问题讨论】:
你为什么要寻找在 Doctrine 中使用的 SQL 查询?为什么不使用存储库或 DQL? 感谢您的回答。我已经更新了我的问题以使其更清楚。现在,我不明白如何编写有关此查询的 DQL。在能够编写这个之后,我将不得不努力编写一个我不需要硬编码网站类别 ID 的那个。此代码目前有效,但我想编写“良好实践”代码。 不知道你所说的“肮脏的工作”,当它是避免它的目标时很难回答;o) 我的意思是我目前正在对网站类别进行循环以创建 SQL 查询,我认为它可以用 DQL 很好地完成。 :// 我希望您知道,您的查询已经是 DQL,您可能指的是查询生成器。我很确定您可能会在子查询中使用HAVING
,这可能会有很大帮助。 ;o)
【参考方案1】:
视频存储库中会执行类似的操作:
$qb->createQueryBuilder(‘v’);
$qb->join(‘v.category’, ‘c’)
->join(‘c.websites, ‘w’)
->where($qb->expr()->eq(‘w.id’, ‘:website’))
->setParameter(‘website’, $your_website_id)
->getQuery()->getArrayResult();
根据编辑,您将需要进行两次查询/这样会更快/
首先获取网站类别和基于这些类别的视频查询
【讨论】:
感谢您的帮助,是的,我做了一个这样的(不像这个简单,我觉得很笨),这接近工作,但它提供的视频没有“所有必需的类别”。它在网站“LOL Pros”(id:1)上获取视频“Lol Casual Player”(id:2),其中网站类别为“Pro”和“League of Legend”,我应该只有视频 1。这是我的问题开始。 实际上根据您的架构 1- 查询应该返回 3 个视频 ID 1,2 和 4,因为网站 1 分配给包含这 3 个视频的类别 1 和 2。视频 2 显示为结果,因为它属于类别 2,网站 1 被分配到... 是的,因为它在网站类别上执行类似于 OR 的操作,但我想要 AND,这是我在 DQL 中找不到的。来自网站 1(“Pro”、“League of Legends”)的视频应该只包含“Pro”和“League Of Legends”猫中的视频,而不仅仅是猫“Pro”或猫“League of Legends”中的视频。在纯 SQL 中是可以的,但在 DQL 中,它就像网站类别中的“OR”。以上是关于Symfony 5 和 Doctrine,找不到使用 3 个相关实体获取结果的方法的主要内容,如果未能解决你的问题,请参考以下文章