Использование JOIN в Symfony2/Doctrine SQL
у меня проблема при попытке использовать QueryBuilder или DQL.
у меня есть следующие отношения:
пользователь профиль RouteGroup 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());
}
}
по очевидной причине я не могу использовать этот код, иначе я перегружу свой сервер, 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.профили - имя отношения вместо сущности - но это тоже не сработало):
$em->createQueryBuilder()
->select('r')
->from('CRMCoreBundle:User', 'u')
->innerJoin('u.profiles','p')
->where('u.id = :user_id')
->setParameter('user_id', $user->getId())
->getQuery()
->getResult();
может кто-нибудь помочь пожалуйста???
UPDATE: я попробовал решение 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'.
если я изменю " - >select ('u, r') "на"- >select('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.
3 ответов
попробовав некоторые альтернативы, я обнаружил, что могу сделать обратный поиск, начиная с маршрутов для пользователей. Решение было следующим:--2-->
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();
в вашем DQL вы получаете пользователей, но вы спросили, как получить маршруты. Что на самом деле вам нужно?
в любом случае, в RoutesRepository:
$this->createQueryBuilder("r")
->innerJoin("r.Profiles", "p")
->innerJoin("p.User", "u")
->where("u=:user")->setParameter("user", $user)
Я не мог понять связи, но я думаю, что вы можете изменить это, чтобы отразить свой код. Вы должны использовать innerJoin, не leftJoin.
Я не эксперт с доктриной, но просто решил очень похожую проблему. Я исправил свою проблему, включив все сущности, которые вы использовали в соединениях в 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();
Я не знаю точно, почему, но если вы не включаете сущности, то гидратор не знает об псевдонимах, которые вы используете для сущностей.
надеюсь, это поможет.