我对SQL有非常基本的了解,不知道如何修改我的查询,因此它会返回预期的结果。
我的实体Activity
有一个字段成员(manyToMany关系)。一项活动可以由几个成员完成。
我想选择特定成员不参与的所有活动。我知道会员的身份证(我的变量$selfId
)。
以下是我在 ActivityRepository 中所做的事情:
public function getCollectiveActivities($selfId)
{
$qb = $this->createQueryBuilder('a');
$qb->join('a.members', 'm')
->where('m.id != :selfId')
->setParameter('selfId', $selfId);
return $qb
->getQuery()
->getResult();
}
我的问题:当一个活动“拥有”两个或更多成员时,如果其中一个成员将$ selfId作为id,则此活动最终会出现在我的查询结果中。 但由于此活动的其中一个成员的ID为$ selfId,因此不应返回。我做错了什么?
我认为我需要更加严格,我只是不知道如何。 假设我有两个活动:
activity1 which is owned by member1 and member2 activity2 which is owned by member3 and member4
$ selfId = 3(这意味着我不想获取member3拥有的活动)
据我所知,join子句可能会返回如下行:
activity1 | memberId: 1 (different from selfId = 3 so activity1 will be fetched) activity1 | memberId: 2 (different from selfId = 3 so activity1 will be fetched) activity2 | memberId: 3 (= selfId so activity2 shouldn't be fetched) activity2 | memberId: 4 (different from selfId = 3 so activity2 WILL be fetched. PROBLEM???)
其他人已经遇到了同样的问题,发现了this solution和this one,但他们看起来有些笨拙。关于如何改进它们的任何线索都是受欢迎的。
答案 0 :(得分:1)
您必须专门选择想要保湿的结果。你看到的问题是你只是选择活动。
然后,当您调用$ activity-> getMembers()时,会员会延迟加载,但这不会考虑您的查询。
你可以这样避免:
public function getCollectiveActivities($selfId)
{
$qb = $this->createQueryBuilder('a');
$qb->addSelect('m');
$qb->join('a.members', 'm')
->where('m.id != :selfId')
->setParameter('selfId', $selfId);
return $qb
->getQuery()
->getResult();
}
这意味着您获取的活动已经使其成员保持水分并受查询条件的限制。
答案 1 :(得分:0)
public function getCollectiveActivities($selfId)
{
return $this->createQueryBuilder('a')
->join('a.members', 'm')
->where($qb->expr()->neq('c.selfId', $selfId))
->getQuery()
->getResult();
}
答案 2 :(得分:0)
我最终调整了@NtskX发布的a solution。
public function getCollectiveActivities($selfId)
{
$qbMyCollectives = $this->createQueryBuilder('ca');
$qbMyCollectives
->select('ca.id')
->leftJoin('ca.members', 'm')
->where('m.id = :selfId')
->setParameter('selfId', $selfId);
$qb = $this->createQueryBuilder('a');
$qb
->where($qb->expr()->notIn('a.id', $qbMyCollectives->getDQL()))
->setParameter('selfId', $selfId); // I had to declare the parameter one more time
return $qb
->getQuery()
->getResult();
}
我真的以为有人会出现更好的方式来加入,所以其他任何答案都非常受欢迎。