使用Doctrine Query Builder检查值是否存在于两个指定字段中
错误原因
你的报错是DQL语法不规范导致的:在Doctrine的DQL语法中,IN运算符右侧必须是小括号包裹的参数列表/子查询,不能直接跟实体的关联集合字段,解析器遇到IN之后期望读到左括号(,结果读到了标识符p,就抛出了你遇到的语法错误。
正确实现
有两种常用的实现方式,根据你的业务场景选择即可:
写法1:使用MEMBER OF运算符(写法最简单)
专门用于判断给定值是否属于实体的关联集合,代码如下:
return $this->createQueryBuilder('p') ->where('p.project_owner = :val') ->orWhere(':val MEMBER OF p.project_contributors') ->setParameter('val', $value) ->getQuery() ->getResult() ;
如果$value传的是用户ID而非User实体对象,把条件改成IDENTITY(p.project_owner) = :val即可。
写法2:使用JOIN查询(性能更优,适合数据量较大的场景)
MEMBER OF底层会生成子查询,数据量较大时性能不如JOIN写法,代码如下:
return $this->createQueryBuilder('p') ->leftJoin('p.project_contributors', 'pc') ->where('p.project_owner = :val') ->orWhere('pc = :val') // 若$value是用户ID则改为pc.id = :val ->setParameter('val', $value) ->distinct() // 避免同一个项目匹配到多个贡献者时返回重复记录 ->getQuery() ->getResult() ;
注意事项
如果你的project_contributor确实是多对一关联(即一个Project仅对应一个贡献者),不需要用集合判断逻辑,直接把orWhere条件改成p.project_contributor = :val即可。
内容的提问来源于stack exchange,提问作者UXerUIer
相关产品推荐
相关产品推荐

