Doctrine Hydrate 将实体加入到一个数组条目中
Doctrine Hydrate joined Entities into one array-entry
我目前在使用 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
混合,结果将是每个加入的 table/entity.
的额外数组条目
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
,它更接近我想要的,但是连接 table 的结果不是连接列的子数组。
提前感谢每一个有用的提示:)
问候
你的问题是你的映射不好我认为你没有发布和艺术家之间的关系。
你必须在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']);
然后继续...
我目前在使用 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
混合,结果将是每个加入的 table/entity.
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
,它更接近我想要的,但是连接 table 的结果不是连接列的子数组。
提前感谢每一个有用的提示:)
问候
你的问题是你的映射不好我认为你没有发布和艺术家之间的关系。
你必须在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']);
然后继续...