在Symfony2/Doctrine SQL中使用JOIN

Mar*_*tto 14 php doctrine dql query-builder symfony

我在尝试使用QueryBuilder或DQL时遇到问题.

我有以下关系:

用户<-1:n-> Profile <-n:m-> RouteGroup <-1:n-> Route

我想创建一个DQL,列出特定用户有权访问的所有路由.我可以使用以下代码获取此信息:

$usr = $this->container->get('security.context')->getToken()->getUser();
foreach ($usr->getProfiles() as $profile){
    foreach ($profile->getRoutegroups() as $routegroup){
        var_dump($routegroup->getRoutes()->toArray());
     }
}
Run Code Online (Sandbox Code Playgroud)

由于显而易见的原因,我无法使用此代码,否则我将重载我的服务器,大声笑.

我尝试了以下方法:

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();
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗???

更新:我尝试了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();
Run Code Online (Sandbox Code Playgroud)

但我得到了这个错误:

The parent object of entity result with alias 'r' was not found. The parent alias is 'rg'.
Run Code Online (Sandbox Code Playgroud)

如果我改变" - >选择('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.
Run Code Online (Sandbox Code Playgroud)

Mar*_*tto 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();
Run Code Online (Sandbox Code Playgroud)

  • 现在你应该尝试学习左连接和内连接之间的区别,它们是非常不同的,内连接可以为你节省大量的麻烦.最简单的方法; 创建类别有很多产品关系.在获取类别时,请对产品进行内部加工; 您将只获得实际包含产品的类别.非常酷的东西,特别是当你将它与"WITH"子句结合使用时. (2认同)