QueryBuilder一对一关联查询无结果:删除已使用对象的查询问题排查
解决思路:单向OneToOne关联下的QueryBuilder左连接查询问题
首先,我们来拆解你当前QueryBuilder代码的核心问题:
- 你错误地把
AttToken设为了查询主表(通过->from('App\Entity\AttToken', 'att_token')),但你的目标是查询Token表中符合条件的记录,主表应该是Token才对。 - 由于
Token和AttToken是单向OneToOne关联(仅在AttToken中定义了关联关系),你当前的LeftJoin方向完全搞反了,而且没法直接通过关联属性来关联两张表,必须手动指定关联条件。
修正后的QueryBuilder代码
'query_builder' => function (EntityRepository $tokenRepo) { return $tokenRepo->createQueryBuilder('t') ->leftJoin('App\Entity\AttToken', 'att', 'WITH', 't.id = att.idToken') ->where('att.idUtilisateur IS NULL') ->orderBy('t.numSerie', 'ASC'); }
代码细节解释
- 主表定位:从
Token实体仓库创建QueryBuilder,用别名t指代Token,这和你目标SQL中SELECT * FROM token的主表逻辑完全一致。 - 左连接关联:因为是单向关联,我们用
leftJoin的第四个参数WITH手动指定关联规则——t.id = att.idToken,对应你原SQL里的token.id = att_token.id_token_id(这里idToken是AttToken实体中关联Token的属性名,对应数据库字段id_token_id)。 - 过滤条件:
where('att.idUtilisateur IS NULL')对应你原SQL的att_token.id_utilisateur_id IS null,确保只筛选出关联AttToken中用户ID为空的Token记录。 - 排序规则:保持和原SQL一致的
orderBy('t.numSerie', 'ASC')逻辑。
验证生成的SQL
修正后的QueryBuilder会生成和你提供的正确MySQL几乎完全匹配的SQL语句,确保业务逻辑一致:
SELECT t.* FROM token t LEFT JOIN att_token att ON t.id = att.id_token_id WHERE att.id_utilisateur_id IS NULL ORDER BY t.num_serie ASC
调整后就能正确获取你需要的可删除已使用对象的结果了。
内容的提问来源于stack exchange,提问作者Totorux
相关产品推荐
相关产品推荐

