原则 2 使用查询生成器删除

2022-08-30 13:07:03

我有两个实体与 OneToMany 和 .现在我想通过project_id删除所有服务。ProjectServices

第一次尝试:

$qb = $em->createQueryBuilder();
$qb->delete('Services','s');
$qb->andWhere($qb->expr()->eq('s.project_id', ':id'));
$qb->setParameter(':id',$project->getId());

此尝试失败,并显示异常 。没错,该属性不存在,它仅在数据库表中作为外键存在。Entity Service does not have property project_id

第二次尝试:

$qb = $em->createQueryBuilder();
$qb->delete('Services','s')->innerJoin('s.project','p');
$qb->andWhere($qb->expr()->eq('p.id', ':id'));
$qb->setParameter(':id',$project->getId());

这个也生成了一个无效的DQL查询。

任何想法和例子将受到欢迎。


答案 1

您使用的是 DQL,而不是 SQL,因此不要在条件中引用 ID,而应改为引用对象。

因此,您的第一个示例将更改为:

$qb = $em->createQueryBuilder();
$qb->delete('Services', 's');
$qb->where('s.project = :project');
$qb->setParameter('project', $project);

答案 2

如果你真的无法获取项目对象,并且你只需要用id来处理,你可以使用它。

来自学说文档的引用:使用学说进行批量删除有两种可能性。可以发出单个 DQL DELETE 查询,也可以循环访问结果,一次删除一个查询。(下面我只粘贴第一个解决方案)

DQL 查询 到目前为止,批量删除的最有效方法是使用 DQL DELETE 查询。

在我的项目中工作的示例

$q = $em->createQuery('delete from AcmeMyTestBundle:TemplateBlock tb where tb.template = '.intval($templateId));
$numDeleted = $q->execute();

在实体 TemplateBlock 中,我有一个名为 template 的属性,它映射到 db 中的template_id。

但我同意,非常喜欢的方法是使用对象。


推荐