Doctrine Hydrate将Entities加入到一个数组条目中

时间:2015-04-24 08:11:16

标签: doctrine-orm zend-framework2 entity left-join resultset

我目前遇到了Doctrine Hydration的一些问题。我正在使用ZF2来构建API,因此我需要构建一些使用连接的查询。

现在他们看起来有点像这样:

$qb->select(array('r, a'))
   ->from('Release\Entity\Release', 'r')
   ->leftJoin(
       'Artist\Entity\Artist', a',
       \Doctrine\ORM\Query\Expr\Join::WITH, 'a.id = r.artist'
     )
   ->orderBy('r.id', 'ASC');

因此,如果我用AbstractQuery::HYDRATE_ARRAY水合结果,结果将是每个连接表/实体的额外数组条目。

Array
(
    [0] => Array
        (
            [id] => 1
            [artist] => 1
            [title] => A super nice Release
            [digital_release] => DateTime Object
                (
                    [date] => 2014-01-25 00:00:00.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Berlin
                )

            [physical_release] => DateTime Object
                (
                    [date] => 2014-01-25 00:00:00.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Berlin
                )

        )

    [1] => Array
        (
            [id] => 1
            [first_name] => John
            [last_name] => Doe
            [artist_name] => JD and the Beat-Machines
            [created_at] => DateTime Object
                (
                    [date] => 2015-04-17 13:16:18.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Berlin
                )

            [updated_at] => DateTime Object
                (
                    [date] => 2015-04-17 13:16:18.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Berlin
                )

        )

    [2] => Array
        (
            [id] => 2
            [artist] => 14
            [title] => Some other nice album
            [digital_release] => DateTime Object
                (
                    [date] => 2014-02-01 00:00:00.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Berlin
                )

            [physical_release] => DateTime Object
                (
                    [date] => 2014-02-01 00:00:00.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Berlin
                )

        )

    [...]
)

如您所见,相应版本[0]的艺术家存储在数组键[1]中。

如果我最终将结果打印为新的JsonModel($result),这对我来说似乎不太可行。

我想要实现的是像这样的结果

Array
(
    [0] => Array
        (
            [id] => 1
            [artist] => Array
                     (
                         [id] => 1
                         [first_name] => John
                         [last_name] => Doe
                         [artist_name] => JD and the Beat-Machines
                         [created_at] => DateTime Object
                             (
                                 [date] => 2015-04-17 13:16:18.000000
                                 [timezone_type] => 3
                                 [timezone] => Europe/Berlin
                              )

                         [updated_at] => DateTime Object
                              (
                                  [date] => 2015-04-17 13:16:18.000000
                                  [timezone_type] => 3
                                  [timezone] => Europe/Berlin
                              )

                      )
            [title] => A super nice Release
            [digital_release] => DateTime Object
                (
                    [date] => 2014-01-25 00:00:00.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Berlin
                )

            [physical_release] => DateTime Object
                (
                    [date] => 2014-01-25 00:00:00.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Berlin
                )
        )

    [2] => Array
        (
            [id] => 2
            [artist] => Array
                     (
                         [id] => 14

                         [...]

                      )
            [title] => Some other nice album
            [digital_release] => DateTime Object
                (
                    [date] => 2014-02-01 00:00:00.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Berlin
                )

            [physical_release] => DateTime Object
                (
                    [date] => 2014-02-01 00:00:00.000000
                    [timezone_type] => 3
                    [timezone] => Europe/Berlin
                )

        )

    [...]
)

也许某人有一个有用的建议如何获得这样的输出:)

我已经尝试使用AbstractQuery::HYDRATE_SCALAR,它更接近我想要的,但是连接表的结果不是连接列的子数组。

提前感谢每一个有用的提示:)

问候

1 个答案:

答案 0 :(得分:1)

你的问题是你的映射它并不好我认为你没有Release和Artist之间的关系。

您必须在Artist和Release之间设置关系OneToMany。像这样:

On artist side
/**
 * @ORM\OneToMany(targetEntity="Release\Entity\Release", mappedBy="artist")
 */
protected $release;

And Release side
/**
 * @ORM\ManyToOne(targetEntity="Artist\Entity\Artist", inversedBy="release")
 * @ORM\JoinColumn(name="artist", referencedColumnName="idArtist", onDelete="RESTRICT")
 */
protected $artist;

不要忘记艺术家方面实现这样的集合:

public function __construct()
{
    $this->release= new ArrayCollection();
}

有了这个用途:

use Doctrine\Common\Collections\ArrayCollection;

使用此功能,您可以设置发布实体并将艺术家设置为艺术家对象。你会得到你想要的结果。

$release = new Release;
$artist = new Artist;
$release->setArtist($artist);

修改 获得数据后,必须使用它填充实体。

如果您有表格,则必须使用DoctrineHydrator来实现此目的,您的对象将从您的表单中正确补充。这可能需要深入学说文献;) 如果您的数据来自其他任何地方,您可以使用实体的设置者填充您的实体。

例如:

$relaseEntity->setDate($data['date']); // Be carefull to Datetime object for this
$releaseEntity->setName($data['name']);

继续......