2013-03-21 46 views
19

我有两个关联OneToMany,ProjectServices的实体。现在我想通过project_id删除所有的服务。使用查询生成器删除原则2

第一次尝试:

$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()); 

这一个generetate非有效DQL查询过。

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

回答

40

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

所以,你的第一个例子将改变到:

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

第三行可以改写如下:$ qb-> where('s.project =:project'); – Oli 2014-12-11 15:26:56

6

如果你真的不能得到项目对象,你必须处理只有ID,您可以使用此。

来自原则文档的引用: 使用Doctrine进行批量删除有两种可能性。您可以发出单个DQL DELETE查询,也可以迭代一次删除它们的结果。 (下面我只粘贴第一个解决方案)

DQL查询 批量删除的最有效的方法是使用DQL DELETE查询。在我的项目

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

曾在实体TemplateBlock

例如,我有被映射在分贝template_id属性调用模板。

但我同意高度喜欢的方式是使用对象。

+9

不要在家里这样做,请注意SQL注入! – chteuchteu 2017-05-29 18:47:10