Symfony 6.2 QueryBuilder中NOT IN语句失效问题求助
解决QueryBuilder中NOT IN排除已添加好友的问题
你不需要用原生SQL就能解决这个问题,核心问题是直接将实体集合传入NOT IN参数不符合Doctrine QueryBuilder的要求,以下是两种可行的修复方案:
方案一:转换为好友ID数组传入
直接传实体集合会导致Doctrine无法正确解析,需要先把好友实体转换为ID数组,再传入参数:
public function findBySearchFriend(Utilisateur $user, $value = null): array { // 将好友实体集合转为ID数组 $friendIds = array_map(function(Utilisateur $friend) { return $friend->getId(); }, $user->getAmis()->toArray()); $qb = $this->createQueryBuilder('u') ->andWhere('u.pseudo LIKE :val') ->setParameter('val', '%'.$value.'%') ->andWhere('u != :user') ->setParameter('user', $user); // 避免空数组导致SQL语法错误,仅当有好友时添加NOT IN条件 if (!empty($friendIds)) { $qb->andWhere('u.id NOT IN (:friendIds)') ->setParameter('friendIds', $friendIds); } return $qb->orderBy('u.id', 'ASC') ->setMaxResults(10) ->getQuery() ->getResult(); }
方案二:利用Doctrine的关联成员查询
如果你的Utilisateur实体和好友是双向关联关系(比如$amis是ManyToMany类型的关联字段),可以直接用NOT MEMBER OF语法简化查询:
public function findBySearchFriend(Utilisateur $user, $value = null): array { return $this->createQueryBuilder('u') ->andWhere('u.pseudo LIKE :val') ->setParameter('val', '%'.$value.'%') ->andWhere('u != :user') ->setParameter('user', $user) ->andWhere(':user NOT MEMBER OF u.amis') // 注意:这里的`u.amis`要和你实体中反向关联的字段名一致 ->orderBy('u.id', 'ASC') ->setMaxResults(10) ->getQuery() ->getResult(); }
关键注意事项
- 方案一中必须判断好友ID数组是否为空,否则用户无好友时会触发
NOT IN ()的SQL语法错误。 - 方案二中要确保实体的关联关系是双向的,且反向关联字段名称与代码中的
u.amis一致。
内容的提问来源于stack exchange,提问作者Easrim
相关产品推荐
相关产品推荐

