1

doctrine は、クエリを実行するときにエンティティのすべてのフィールドを常に選択する必要があると思います。Kitpages の DataGrid バンドルを次のコードで使用しています。

    // create query builder
    $repository = $this->getDoctrine()->getRepository('MyApplicationBundle:Application');
    $queryBuilder = $repository->createQueryBuilder('a', 'u');
    $queryBuilder->leftJoin('a.created_by', 'u'); // join user info

    $gridConfig = new GridConfig();
    $gridConfig
        ->setCountFieldName('a.id')
        ->addField(new Field('a.name', array('label'=>'col.name', 'sortable' => true, 'filterable'=>true)))
        ->addField(new Field('a.app_type', array('label'=>'col.type', 'sortable' => true, 'filterable'=>true)))
        ->addField(new Field('a.created_by', array(
            'label'=>'col.user',
            'sortable' => true,
            'filterable'=>true,
            'nullIfNotExists'=>true,
            'formatValueCallback' => function($createdBy) {
                if($createdBy instanceof \My\UserBundle\Entity\User)
                    return $createdBy->getName();
            }
        )))
    ;

これで、created_by が null であるエンティティと、fos_user テーブルの行を参照する ID であるエンティティがいくつかあります。実際に createdBy に値を持つエンティティの名前の値を取得する必要がありますが、クリエーターのグリッドのすべての行に空の列を取得しています。

ドクトリンが取得しているSQLを確認できるログです。

SELECT a0_.id AS id0, a0_.name AS name1, a0_.app_type AS app_type2, a0_.public AS public3, a0_.enabled AS enabled4, a0_.likegating AS likegating5, a0_.mobile_optimized AS mobile_optimized6, a0_.share_data AS share_data7, a0_.created_date AS created_date8, a0_.updated_date AS updated_date9 FROM application a0_ LEFT JOIN fos_user f1_ ON a0_.created_by_id = f1_.id LIMIT 15 OFFSET 15

全然選ばないa0_.created_by_id。そのフィールドを含めるように選択するにはどうすればよいですか? フィールドを「u.name」に変更してみましたが、役に立ちませんでした。

注意:コードを変更してaddSelect('u')、受け入れられた回答の言及のようなものを含めることに加えて'formatValueCallback'、変数を配列として扱うように変更しました。そのようです:

'formatValueCallback' => function($createdBy) {
    if(isset($createdBy['name']))
        return $createdBy['name'];
}
4

1 に答える 1

3

つまり、関係が存在するにもかかわらず、基本的に u.name を取得していませんか?

変化する:

$queryBuilder = $repository->createQueryBuilder('a', 'u');

createQueryBuilder は、アプリケーション オブジェクトのエイリアスとなる引数を 1 つだけ受け取ります。「u」は無視されます。

に:

$queryBuilder = $repository->createQueryBuilder('a');
$queryBuilder->addSelect('u');

これにより、ユーザー エンティティが設定されます。

a0_.created_by_id は、リンクされたユーザー オブジェクトを取得するために結合ステートメントで使用されるため、select 句には表示されません。created_by_id が実際にアプリケーション オブジェクトに格納されることはありません。上記の変更を行った後、SQL を確認すると、一連のユーザー属性が選択されていることがわかります。

================================================== =========

今後の参考のために、これはリポジトリがクエリ ビルダーを作成するために使用するコードです。

class Doctrine\ORM\EntityRepository

public function createQueryBuilder($alias)
{
    return $this->_em->createQueryBuilder()
        ->select($alias)
        ->from($this->_entityName, $alias);
}
于 2013-08-23T14:27:35.183 に答える