Symfony3.4+Doctrine:查询未关联office_user表的USER实体
解决Symfony 3.4 + Doctrine中查询未关联Office的User实体问题
你的问题核心在于当前的DQL查询缺少过滤关联不存在的用户的关键条件,而且多对多关联的查询需要精准匹配你的SQL思路。下面给你两种对应你原有SQL写法的正确DQL实现:
方法一:LEFT JOIN + 关联为空判断
对应你第一条SQL的逻辑,在DQL里需要明确筛选出office关联完全不存在的用户:
$query = $this->getEntityManager() ->createQuery( 'SELECT u FROM AppBundle:User u LEFT JOIN u.office o WHERE u.role = :role AND o IS NULL' ); $query->setParameters([ 'role' => 'ROLE_USER', ]); return $query->getResult();
这里的关键是添加了AND o IS NULL,这会把所有没有关联任何Office的User实体筛选出来,和你第一条SQL的效果完全一致。
方法二:NOT IN子查询
对应你第二条SQL的思路,通过子查询获取所有已关联Office的用户ID,再排除这些ID得到目标结果:
$query = $this->getEntityManager() ->createQuery( 'SELECT u FROM AppBundle:User u WHERE u.role = :role AND u.id NOT IN ( SELECT u2.id FROM AppBundle:Office o JOIN o.users u2 )' ); $query->setParameters([ 'role' => 'ROLE_USER', ]); return $query->getResult();
子查询通过关联Office的users集合,提取所有已关联的用户ID,外层查询直接排除这些ID即可得到未关联的用户。
关于你提到的「Office集合为空但数据库有数据」的说明
这是Doctrine默认的**延迟加载(LAZY)**机制导致的:当你直接打印User实体时,关联的Office集合还没从数据库加载,所以看起来是空的。如果需要在查询时就加载关联数据,可以用LEFT JOIN FETCH u.office o,但对你的需求来说,因为最终只需要未关联的用户,他们的Office集合本来就是空的,所以不需要额外做这个操作。
内容的提问来源于stack exchange,提问作者Rudolf Grabowski
相关产品推荐
相关产品推荐

