2012-11-13 2 views
10

QueryBuilder 또는 DQL을 사용하는 동안 문제가 있습니다.Symfony2/Doctrine SQL에서 JOIN 사용

나는 다음과 같은 관계가 있습니다

사용자가 < -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(); 

누군가가 도와 줄 수 있습니까 ???

업데이트 : 젤코의 솔루션을 시도하고이 스크립트를 만든 :

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') "to"-> 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. 
+1

업데이트에 응답하려면 u 및 r을 선택할 수 없습니다. r로가는 길에있는 모든 항목도 선택해야합니다. 그래서 당신은 select ('u, p, rg, r')가 필요합니다. – intrepion

답변

20

몇 가지 대안을 시도한 후에 나는 경로에서 사용자로 시작하여 역 조회를 할 수 있다는 것을 알았습니다. 해결책은 다음과 같습니다 :

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(); 
+2

이제는 왼쪽 조인과 내부 조인의 차이를 배우려고 시도해야합니다. 그들은 매우 다르며 내부 조인은 두통의 두 배를 저장할 수 있습니다. 가장 간단한 방법; 카테고리 생성에는 많은 제품 관계가 있습니다. 범주를 가져올 때 제품의 내부 조인; 당신은 실제로 그것 안에 제품이있는 종류 만 얻을 것이다. 정말 멋진 일, 특히 당신이 "WITH"절과 결합 할 때. – Zeljko

+0

문제 없습니다. 나는 이미 내부 조인과 왼쪽 조인의 차이점을 알고 있습니다. –

3

DQL에서 사용자 bu 경로를 가져 오는 방법을 묻지 않았습니다. 실제로 필요한 게 뭐야? RoutesRepository에서 어쨌든

는 :

$this->createQueryBuilder("r") 
    ->innerJoin("r.Profiles", "p") 
    ->innerJoin("p.User", "u") 
    ->where("u=:user")->setParameter("user", $user) 

나는 관계를 이해하지 않을 수 있습니다하지만 난 당신이 코드를 반영하기 위해 변경할 수 있다고 생각합니다. leftJoin이 아닌 innerJoin을 사용해야합니다.

+0

안녕하세요, 당신의 해결책을 시도했지만 다른 문제가 있습니다. 위의 질문을 업데이트했습니다. 좀 봐 주시겠습니까? 감사합니다 –

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(); 

나는 이유를 정확하게 알 수는 없지만,이 엔티티를 포함하지 않는 경우 다음 하이드는 엔티티에 사용하는 별칭에 대해 알고하지 않습니다.

나는 이것이 도움이되기를 바랍니다.