Doctrine查询中实现数组不在数组中的条件报错求助
解决Doctrine中"数组不在数组中"的多列NOT IN问题
我之前也碰到过这个坑!Doctrine ORM的DQL语法本身并不支持这种多列组合的IN/NOT IN操作——它的语法解析器无法识别(:currentUserId, user.id)这种多值组合的写法,这就是你看到语法错误的核心原因。下面给你几个可行的解决思路:
方案1:直接使用原生SQL查询(最快捷)
既然你的原生SQL已经在phpMyAdmin里验证可行,那直接用Doctrine的数据库连接执行原生SQL是最省心的方式:
$em = $this->getDoctrine()->getManager(); $connection = $em->getConnection(); $sql = ' SELECT user.* FROM user LEFT JOIN collab_invitation_target invite ON user.id = invite.target_user_id WHERE (:currentUserId, user.id) NOT IN (:inviteArr) '; $stmt = $connection->prepare($sql); $stmt->execute([ 'currentUserId' => $this->getUser()->getId(), 'inviteArr' => $invites, ]); // 如果需要将结果转为Doctrine实体对象 $users = $em->getRepository('FangoUserBundle:User')->hydrate($stmt->fetchAllAssociative());
这个方法完全复用你已经验证过的SQL逻辑,不需要做任何语法调整。
方案2:用DQL表达式手动拼接条件(纯ORM方式)
如果你不想脱离DQL的ORM环境,可以把多列组合拆成单个条件的逻辑组合:
$em = $this->getDoctrine()->getManager(); $qb = $em->getRepository('FangoUserBundle:User') ->createQueryBuilder('user') ->leftJoin('user.collabInvitationTarget', 'invite'); $expr = $qb->expr(); $excludeConditions = []; $currentUserId = $this->getUser()->getId(); // 遍历所有要排除的(id1, id2)组合 foreach ($invites as $pair) { // 每个组合拆成两个相等条件的AND $excludeConditions[] = $expr->andX( $expr->eq(':currentUserId', $pair[0]), $expr->eq('user.id', $pair[1]) ); } // 如果有需要排除的条件,添加NOT(OR(...))逻辑 if (!empty($excludeConditions)) { $qb->where($expr->not($expr->orX(...$excludeConditions))); } $qb->setParameter('currentUserId', $currentUserId); $users = $qb->getQuery()->getResult();
这个思路的核心是把(a,b) NOT IN ((x,y),(m,n))转换成NOT ((a=x AND b=y) OR (a=m AND b=n)),完全符合DQL的语法规则。
方案3:自定义DQL函数(适合长期复用)
如果你的项目中经常需要这种多列IN/NOT IN的逻辑,可以自定义一个DQL函数来扩展Doctrine的语法。你需要创建一个继承自Doctrine\ORM\Query\AST\Functions\FunctionNode的类,实现多列IN的解析逻辑,然后在Doctrine配置中注册这个函数。不过这个方案步骤稍多,适合有一定Doctrine扩展经验的场景。
内容的提问来源于stack exchange,提问作者Mehmet S.
相关产品推荐
相关产品推荐

