【问题标题】:Doctrine2 One-To-Many, Self-referencing relationshipDoctrine2 一对多、自引用关系
【发布时间】:2012-09-24 05:09:55
【问题描述】:

在我的“主题”实体中,我有一个一对多的自引用关系$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。如果父母没有孩子,我只会得到一个空值作为它的名字:

  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)

根据 Mark 的建议,我已将子实体的名称字段重命名:

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'

【问题讨论】:

    标签: symfony doctrine-orm one-to-many relationship self-reference


    【解决方案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 查询时获得的结果相匹配。您当前正在做的是从两个数据库表中获取两个值。您真正想要的是格式化为数组的两个部分实体。

    您可以尝试使用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();
    

    【讨论】:

    • 我仍然得到错误的数组格式。我已经编辑了我的问题以添加更多结果
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    相关资源
    最近更新 更多