2

Cheque、Efectivo、Debitoなどの他のいくつかのエンティティの親クラスであるAbonoというエンティティがあります。私のアプリケーションでは、次のようなDQLステートメントを持つリポジトリクラスを使用して、クラスAbonoのインスタンスであるすべてのオブジェクトをクエリしています(コードは実際のオブジェクトの簡略化されたバージョンです)。

$dql = "SELECT ab FROM FranquiciaBundle:Abono AS ab";
return $em->createQuery($dql)
          ->getResult();

私のテンプレートでは、次のような結果を示しています(ここでも簡略化されたコード):

{% for abono in abonos %}
    <tr>
        <td>{{ abono.id }}</td>
        <td>{{ abono.tipo }}</td>
    </tr>
{% endfor %}

そのテーブルに5000のレコードがあり、プロファイラーは、アプリが予想どおりに1回ではなく、5000回データベースにヒットしていると言っているので、getArrayResult()代わりにを使用してqueリポジトリを少し変更しますgetResult()が、問題は文{{ abono.tipo }}がメソッドであるということですデータベースに格納されているプロパティではなく、オブジェクトの呼び出しであるため、結果の配列にハイドレイトされることはありません。

だから私の質問は、データベースに一度だけヒットするオブジェクトの配列を取得するにはどうすればよいですか?

更新:getTipo()クラスAbonoのメソッドは、すべてのオブジェクトの遅延静的バインディングクラス名を返します。これは関連付けではありません。

public function getTipo()
{
    $className = get_called_class();
    $pos = strrpos($className,'\\');
    return substr($className, $pos+1);
}
4

3 に答える 3

6

わかりました私は私の問題の原因を見つけました。

Association の逆側にあるオブジェクトをクエリする場合、doctrine は常にそれらのエンティティを取得してプロキシ インスタンスを作成するようです。たとえそれらのエンティティがコントローラーまたはテンプレートで必要とされていなくてもです。そのため、プロフィール バーに表示されていたデータベースへの膨大なヒット数は、私が求めていない情報を検索する際にドクトリンが邪魔をしていることを示していました。

解決策は、次のようにリポジトリで部分ロードの使用を強制することです。

$dql = "SELECT ab FROM FranquiciaBundle:Abono AS ab";
return $em->createQuery($dql)
          ->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
          ->getResult();

詳細はこちら

于 2013-01-06T18:10:41.673 に答える
2

フェッチ結合を使用して関連情報を取得し、最初のクエリと一緒に水和することができます。

"SELECT ab, tipo FROM FranquiciaBundle:Abono AS ab JOIN ab.tipo"

参照: http://doctrine-orm.readthedocs.org/en/2.0.x/reference/dql-doctrine-query-language.html#joins

于 2013-01-03T15:03:59.173 に答える
1

Erik は正しいですが、最適化のために SQL を実行する必要はありません。doSelectJoinAll がそのトリックを行います。

于 2013-01-03T15:33:23.867 に答える