我正在尝试执行以下查询:
$qb = $this->getEntityManager()->createQueryBuilder();
$referredUsers = $qb->select(['referred', 'referral', 'match'])
->from('ProjectContestBundle:UserParticipation', 'up')
->innerJoin('ProjectUserBundle:User', 'referred', 'WITH', 'up.user = referred')
->innerJoin('ProjectUserBundle:User', 'referral', 'WITH', 'up.referral = referral.referralCode')
->innerJoin('ProjectContestBundle:UserParticipation', 'upr', 'WITH', 'upr.user = referral')
->innerJoin('ProjectMatchBundle:Match', 'match', 'WITH', 'match.owner = referred')
->where('up.contest = :contest')->andWhere('upr.contest = :contest')
->setParameter('contest', $contest)
->getQuery()->getResult();
我期待一个行数组,其中每一行的类型为[User, User, Match]
,但Doctrine会返回一个包含实体混合内容的普通数组。
然后我尝试用以下方法简化:
$qb = $this->getEntityManager()->createQueryBuilder();
$referredUsers = $qb->select(['referred.id', 'referral.id', 'match.id'])
->from('ProjectContestBundle:UserParticipation', 'up')
->innerJoin('ProjectUserBundle:User', 'referred', 'WITH', 'up.user = referred')
->innerJoin('ProjectUserBundle:User', 'referral', 'WITH', 'up.referral = referral.referralCode')
->innerJoin('ProjectContestBundle:UserParticipation', 'upr', 'WITH', 'upr.user = referral')
->innerJoin('ProjectMatchBundle:Match', 'match', 'WITH', 'match.owner = referred')
->where('up.contest = :contest')->andWhere('upr.contest = :contest')
->setParameter('contest', $contest)
->getQuery()->getResult();
会产生[{"id":1},{"id":2},{"id":3},{"id":4}]
。如果我在数据库上运行查询它可以正常工作:
SELECT u0_.ID AS ID0, u1_.ID AS ID1, m2_.ID AS ID2 FROM UserParticipation u3_ INNER JOIN users u0_ ON (u3_.user_id = u0_.ID) INNER JOIN users u1_ ON (u3_.l = u1_.referralCode) INNER JOIN UserParticipation u4_ ON (u4_.user_id = u1_.ID) INNER JOIN matches m2_ ON (m2_.ownerID = u0_.ID) AND (m2_.deletedAt IS NULL) WHERE u3_.contest_id = 1 AND u4_.contest_id = 1;
返回:
+-----+-----+-----+
| ID0 | ID1 | ID2 |
+-----+-----+-----+
| 1 | 9 | 1 |
| 1 | 9 | 2 |
| 1 | 9 | 3 |
| 10 | 9 | 4 |
+-----+-----+-----+
所以我尝试添加一些as
和:
$referredUsers = $qb->select(['referred.id as r1', 'referral.id as r2', 'match.id as m'])
->from('ProjectContestBundle:UserParticipation', 'up')
->innerJoin('ProjectUserBundle:User', 'referred', 'WITH', 'up.user = referred')
->innerJoin('ProjectUserBundle:User', 'referral', 'WITH', 'up.referral = referral.referralCode')
->innerJoin('ProjectContestBundle:UserParticipation', 'upr', 'WITH', 'upr.user = referral')
->innerJoin('ProjectMatchBundle:Match', 'match', 'WITH', 'match.owner = referred')
->where('up.contest = :contest')->andWhere('upr.contest = :contest')
->setParameter('contest', $contest)
->getQuery()->getArrayResult();
,结果是正确的!
[{"r1":1,"r2":9,"m":1},{"r1":1,"r2":9,"m":2},{"r1":1,"r2":9,"m":3},{"r1":10,"r2":9,"m":4}]
如果我尝试使用非id版本返回,留下as
我仍然会返回一行行,其中每行是不同的实体,但是我希望有一行{{1如select所示(与MySql原始结果相同,仅与实体相同)。
答案 0 :(得分:2)
简短回答
教义只选择水合物作为关系。
长答案
默认情况下,Doctrine返回“from entity”作为查询的所有者。我的意思是,它将返回此实体的数组,并且它将根据您的映射填充此实体内的其余实体。
我建议您将up.referral
和user.referralCode
更改为关系而不是列。另一个变化是地图用户访问匹配(如果它是一对一的关系)。
让我们简化一下代码:
$qb = $this->getEntityManager()->createQueryBuilder();
//it will return array of UserParticipation
$userParticipations = $qb->select('up, referred, match')
->from('ProjectContestBundle:UserParticipation', 'up')
->innerJoin('up.user','referred')
->innerJoin('up.referralUser', 'referral')
->innerJoin('referred.match', 'match')
->where('up.contest = :contest')
->setParameter('contest', $contest)
->getQuery()->getResult();
$userParticipations
数组中的每个项目都是UserParticipation。您可以通过它访问引荐的($userParticipations[0]->getUser()
),引荐($userParticipations[0]->getReferralUser()
),匹配($userParticipations[0]->getUser()->getMatch()
),等等。
这几乎是你的第一次尝试。
注意以上代码仅在您对地图和数据库进行一些更改时才有效。