14

QueryBuilderまたはDQLを使用しようとしたときに問題が発生しました。

私は次の関係を持っています:

ユーザー<-1:n->プロファイル<-n:m->ルートグループ<-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'.

「->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.
4

3 に答える 3

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();
于 2012-11-13T02:23:23.437 に答える
3

DQLでは、ユーザーをフェッチしていますが、ルートをフェッチする方法を尋ねました。実際に何が必要ですか?

とにかく、RoutesRepositoryで:

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

関係がわからないかもしれませんが、コードを反映するように変更できると思います。leftJoinではなくinnerJoinを使用する必要があります。

于 2012-11-13T01:56:56.937 に答える
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();

正確な理由はわかりませんが、エンティティを含めないと、ハイドレーターはエンティティに使用しているエイリアスを認識しません。

これがお役に立てば幸いです。

于 2014-05-14T11:47:33.097 に答える