5

私の「トピック」エンティティには、1 対多の自己参照関係があり$parent:$childrenます。

class Topic
{
    /** @ORM\Id 
    * @Column(type="integer")
    * @ORM\GeneratedValue(strategy="IDENTITY")
    */
    private $id;

    /** @Column(length=40, unique=true) */
    private $name;

    /**
     * @ORM\ManyToOne(targetEntity="Topic", inversedBy="children")
     */
    private $parent;

    /**
     * @ORM\OneToMany(targetEntity="Topic", mappedBy="parent")
     */
    private $children;
}

テーブルを結合して、次のような親子階層を取得できます。

return $this->getEntityManager()->createQuery('
    SELECT t, c FROM My\xxxBundle\Entity\Topic t 
    LEFT JOIN t.children c
    WHERE t.parent IS NULL
')
->getArrayResult();

正しい出力は次のとおりです。

array
  0 => 
    array
      'id' => int 1
      'name' => string 'Parent 1'
      'slug' => string 'p-1'
      'description' => null
      'children' => 
        array
          0 => 
            array
                'id' => int 2
                'name' => string 'Child 1-1'
                'slug' => string 'c-1-1'
                'description' => null
          1 => 
            array
                'id' => int 3
                'name' => string 'Child 1-2'
                'slug' => string 'c-1-2'
                'description' => null
  1 => 
    array
      'id' => int 4
      'name' => string 'Parent 2'
      'slug' => string 'p-2'
      'description' => null
      'children' => 
        array
          empty
...

しかし、SELECT ステートメントで特定の列をフェッチしようとすると、次のようになります。

SELECT t.name, c.name FROM My\xxxBundle\Entity\Topic t

子エンティティのフラットな配列、つまりのみを取得しc.nameます。親に子がいない場合は、その名前に null 値を取得します。

  1 => 
    array (size=1)
      'name' => string 'Child 1-1' (length=14)
  2 => 
    array (size=1)
      'name' => string 'Child 1-2' (length=14)
  3 => 
    array (size=1)
      'name' => null
  4 => 
    array (size=1)
      'name' => string 'Child 3-1' (length=5)

マークの提案で、子エンティティの名前フィールドの名前を変更しました。

SELECT t.name, c.name AS child_name FROM My\xxxBundle\Entity\Topic t

しかし、私はまだ間違った形式を取得します:

array
  0 => 
    array
      'name' => string 'Parent 1'
      'child_name' => string 'Child 1-1'
  1 => 
    array
      'name' => string 'Parent 1'
      'child_name' => string 'Child 1-2'
  2 => 
    array
      'name' => string 'Parent 2'
      'child_name' => string 'Child 2-1'
4

1 に答える 1

7

問題は、同じ名前の 2 つのフィールド (トピックの名前フィールドと子の名前フィールド) を選択することです。これらの名前は、配列キーを作成するときに互いに競合します。この問題の解決策は、フィールドの 1 つの名前を変更することです。

SELECT t.name, c.name AS child_name FROM My\xxxBundle\Entity\Topic t

フラット配列を取得する理由は、エンティティを選択しているのではなく、これらのエンティティからの個々の値を選択しているためです。

詳細については、DQL ドキュメントを参照してください: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#select-queries

編集 クエリから得られる現在の結果は論理的です。これは、同等の SQL クエリを実行したときに得られるものと一致します。現在行っていることは、2 つのデータベース テーブルから 2 つの値をフェッチすることです。本当に必要なのは、配列にフォーマットされた 2 つの部分的なエンティティです。

あなたが試すことができるのは、Partialsを使用することです。これは、エンティティのいくつかのフィールドのみを選択する教義の方法です。これを ->getArrayResult() と組み合わせると、おそらく正しい出力が得られます

return $this->getEntityManager()->createQuery('
    SELECT partial t.{name}, partial c.{name}
    FROM My\xxxBundle\Entity\Topic t 
    LEFT JOIN t.children c
    WHERE t.parent IS NULL
')
->getArrayResult();
于 2012-09-24T09:17:01.747 に答える