如何使用Doctrine QueryBuilder删除多个实体

时间:2018-04-26 15:20:31

标签: sql symfony doctrine

我正在开发一个基于Symfony 2.8的项目来管理联系人。用户可以从列表中选择任意数量的联系人,并且应该能够一次删除所有选择的联系人。如何在单个Query Builder语句中完成此操作?

// Contact entity uses a GUID as ID
$guids = array(...);

try {
    $this->getEntityManager()->getConnection()->beginTransaction();  

    $qb = $this->getEntityManager()->getConnection()->createQueryBuilder()
        ->delete('AppBundle:Contact', 'c')                
        ->where('c.guid in (:guids)')
        ->setParameter(':guids', array($guids, Connection::PARAM_STR_ARRAY));

    log($qb->getSql());
    $qb->execute();

    $this->getEntityManager()->flush();            
    $this->getEntityManager()->getConnection()->commit();
} catch (\Exception $ex) {
    // Rollback the transaction
    $this->getEntityManager()->getConnection()->rollback();
} 

1。问题

使用AppBundle:Contact(在构建SELECT语句时没有任何问题时)对实体进行寻址不起作用。这是日志输出:

Query: DELETE FROM AppBundle:Contact c WHERE c.guid in (:guids)
Exception: Doctrine\DBAL\SQLParserUtilsException: Value for :Contact not found in params array. Params array key should be "Contact" in

2。问题

使用表名(->delete('contact', 'c'))也不起作用:

Query: DELETE FROM contact c WHERE c.guid in (:guids)
Exception: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'c WHERE c.guid in ('Array')'

第3。问题

删除单个实体也不起作用:

->delete('contact', 'c')                
->where('c.guid = (:guid)')
->setParameter(':guid', $guids[0]);

Query: DELETE FROM contact c WHERE c.guid = :guid
Exception: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'c WHERE c.guid = 'E7516B91-0549-4FFB-85F2-4BD03DC3FFC1''

她可能出错了什么?

2 个答案:

答案 0 :(得分:1)

<强>第一。问题。将setParameter行更改为以下内容,您不需要使用:以param的名义。

->setParameter('guids', $guids);

第二个问题 - 如果您正在处理queryBuilder,则不应使用真实的表名。

第三个问题 - 您的逻辑不正确。如果要删除单个

$qb = $this->getEntityManager()->createQueryBuilder()
    ->delete('AppBundle:Contact', 'c')                
    ->where('c.guid = :guid)')
    ->setParameter('guid', $guids[0]);

<强>另外

我真的不知道你正在使用什么学说版本,但是

$this->getEntityManager()->getConnection()->createQueryBuilder() - 似乎错了,因为如果你想执行RAW SQL,通常会得到连接。

尝试更改为

$qb = $this->getEntityManager()->createQueryBuilder()

如果是数组,你需要在变量周围使用括号。检查以下代码

$queryBuilder->andWhere('r.id IN (:ids)')
             ->setParameter('ids', $ids);

答案 1 :(得分:1)

除非您想要执行原始SQL,否则您不必使用实体管理器的连接,因此您可以将$this->getEntityManager()->getConnection()->createQueryBuilder()替换为 $em->createQueryBuilder()

您可以执行类似

的操作
$qb = $this->createQueryBuilder()
    ->delete('AppBundle:Contact', 'c')                
    ->where('c.guid in (:guids)')
    ->setParameter(':guids', $guids);

如果你想记录/执行它

$query = $qb->getQuery();
log($query->getSql());
$query->execute();

您也不需要添加beginTransactionrollback,如果查询失败并抛出异常,则doctrine将自动回滚。