1

Userエンティティとエンティティがあり、Book両方が結合されていると仮定しますUser.bookId = Book.id(これは、ユーザーが特定の本を所有していることを示します。リレーション タイプは oneUserToManyBook です)。

BooksDoctrine の DQL または QueryBuilder を使用して、読み取ったすべてのパフォーマンスに適したフェッチを実行したい場合User、Symfony2/Doctrine2 Web アプリケーションでこれを実装してUser、Twig テンプレートのループで使用できるようにする最良の方法は何ですか?

小枝

{% for user in users %}
   {{ user.name|e }}
       {% for address in user.getAddressesByUserId(user.getId()) %}
           {{ address.city }}
       {% endfor %}
{% endfor %}

2 つのアプローチがありますが、どちらも私の目標にはつながりません。

最初のアプローチ

カスタム リポジトリ クラスを作成しますBookRepository

public function getBooksOwnedByUser($user_id) {
    return $em->createQuery('SELECT b.title
                             FROM MyBundle\Entity\User u,
                                  MyBundle\Entity\Book b
                             WHERE u.book_id = b.id'
                             AND u.id = :user_id)
              ->setParameter('user_id', $user_id)
              ->getResult();
}

問題getBooksOwnedByUser(): 正常に動作しますが、Twig テンプレートを呼び出すことができません (エンティティUserには関連付けられていませんが、のサブクラスであるリポジトリに関連付けられているためです) Doctrine\ORM\EntityRepository


2番目のアプローチ

上記と同じクエリを実行します。 myではなく、エンティティ クラスUserRepositoryで直接実行します。User

ここでの問題: Twig テンプレートでこのメソッドを呼び出すことはできますがEntityManagerUserエンティティ クラスで を使用することはできません (使用すべきではありません)。

4

1 に答える 1

2

User から Books への関係を作成するのが最善です。この関係を作成したと仮定すると、次のようにクエリを作成できます。

public function getBooksOwnedByUser($user_id) {
    return $em->createQuery('SELECT u, b
                            FROM MyBundle\Entity\User u
                            JOIN u.books b
                            WHERE  u.id = :user_id')
                        ->setParameter('user_id', $user_id)
                        ->getResult();
}

次に、コントローラーで:

$em = $this->getDoctrine()->getManager();
$user_with_books = $em->getRepository('MyBundle\Entity\User')
    ->getBooksOwnedByUser($user->getId());

return $this->render('YourTemplate.html.twig', array(
        'user_with_books' => $user_with_books,
));

小枝で:

{% for book in user.books %}
    {{ book.title }}
{% endfor %}

いくつかの考慮事項:

  1. 複数のユーザーの場合、クエリを変更する必要があります (遅延読み込みは可能ですが、お勧めしません)。
  2. 大量のデータの場合は、スカラー結果 (配列) を取得することでパフォーマンスを向上させることができます
  3. 組み合わせることができないユーザー用の別のクエリが必要な場合は、別の変数 (オブジェクトまたは配列) を格納する必要があります。そのため、「user_with_books」と名付けました。ただし、テンプレートにこのユーザーしかない場合は、「ユーザー」と呼ぶこともできます。
  4. user.getAddressesByUserId(user.getId())<-- 1 つのモデルからクエリにデータを渡すのは、コントローラー (またはサービス) の責任です。ベスト プラクティスは、テンプレートでこれを行うことを避けることです。

答え: カスタム リポジトリ メソッドは関数であるため、何もできません。関数自体はデータを表しません。これは、その関数で実際のデータを取得して表示できる方法です。

于 2013-08-16T17:13:40.693 に答える