我在尝试使用QueryBuilder或DQL时遇到问题。
我有以下关系:
用户< -1:n->简介< -n:m-> RouteGroup< -1:n->路线
我想创建一个列出特定用户有权访问的所有路由的DQL。 我可以使用以下代码获取此信息:
$usr = $this->container->get('security.context')->getToken()->getUser();
foreach ($usr->getProfiles() as $profile){
foreach ($profile->getRoutegroups() as $routegroup){
var_dump($routegroup->getRoutes()->toArray());
}
}
由于显而易见的原因,我无法使用此代码,否则我将重载我的服务器,LOL。
我尝试了以下方法:
DQL:
$em->createQuery('SELECT p FROM CRMCoreBundle:User u
JOIN CRMCoreBundle:Profile p
JOIN CRMCoreBundle:RoleGroup rg
JOIN CRMCoreBundle:Role r
WHERE
u.id=:user')
->setParameter('user', $user->getId())
->getResult();
QueryBuilder(我尝试使用u.profiles - 关系的名称而不是实体 - 但这也不起作用):
$em->createQueryBuilder()
->select('r')
->from('CRMCoreBundle:User', 'u')
->innerJoin('u.profiles','p')
->where('u.id = :user_id')
->setParameter('user_id', $user->getId())
->getQuery()
->getResult();
有人可以帮忙吗???
更新:我尝试了Zeljko的解决方案并制作了这个脚本:
return $this->getEntityManager()
->createQueryBuilder()
->select('u, r')
->from('CRMCoreBundle:User', 'u')
->innerJoin('u.profiles','p')
->innerJoin('p.routegroups','rg')
->innerJoin('rg.routes','r')
->where('u.id = :user_id')->setParameter('user_id', $user->getId())
->getQuery()
->getResult();
但我收到了这个错误:
The parent object of entity result with alias 'r' was not found. The parent alias is 'rg'.
如果我改变“ - >选择('u,r')”到“ - >选择('r')”我得到这个:
[Semantical Error] line 0, col -1 near 'SELECT r FROM': Error: Cannot select entity through identification variables without choosing at least one root entity alias.
答案 0 :(得分:22)
在尝试了一些替代方案后,我发现我可以进行反向查找,从路径开始到用户。解决方案如下:
return $this->getEntityManager()
->createQueryBuilder()
->select('r')
->from('CRMCoreBundle:Route', 'r')
->innerJoin('r.routegroup','rg')
->innerJoin('rg.profiles','p')
->innerJoin('p.users','u')
->where('u.id = :user_id')
->setParameter('user_id', $user->getId())
->getQuery()
->getResult();
答案 1 :(得分:3)
在您的DQL中,您正在提取用户,但您询问了如何获取路由。你究竟需要什么?
无论如何,在RoutesRepository中:
$this->createQueryBuilder("r")
->innerJoin("r.Profiles", "p")
->innerJoin("p.User", "u")
->where("u=:user")->setParameter("user", $user)
我可能不理解这种关系,但我认为你可以改变它以反映你的代码。你必须使用innerJoin,而不是leftJoin。
答案 2 :(得分:3)
我不是Doctrine的专家,只是解决了一个非常类似的问题。我通过在语句的SELECT部分中包含您在联接中使用的所有实体来解决我的问题。
我没有对此进行测试,但这应该可行。
$em->createQuery('SELECT u, p, rg, r FROM CRMCoreBundle:User u
JOIN CRMCoreBundle:Profile p
JOIN CRMCoreBundle:RoleGroup rg
JOIN CRMCoreBundle:Role r
WHERE
u.id=:user')
->setParameter('user', $user->getId())
->getResult();
我不确切知道原因,但如果您不包含实体,那么保水器就不知道您为实体使用的别名。
我希望这会有所帮助。