Symfony 4 - ManyToMany - FetchData(ORM 获取或存储库查询)
Symfony 4 - ManyToMany - FetchData (ORM Fetch or Repository Query)
我尝试从多对多关系中获取数据。我发现了很多关于这个主题的 videos/posts/blogs,但我无法让它工作(或理解)。我需要帮助。
太棒了!我有 "Formation" 和 "Module" class。每个 "Formation" 可以有很多 "Module" 反之亦然。
预期结果
我想获得 "Formation" array(all)/item(byId) 以及所有 "Modules" link 在“->modules”属性中编辑它。
Class阵型
/***
* @var \Doctrine\Common\Collections\Collection|Module[]
* @ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Module", inversedBy="formations")
* @ORM\JoinTable(
* name="entreprises_formation_module",
* joinColumns={
* @ORM\JoinColumn(name="formation_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="module_id", referencedColumnName="id")
* }
* )
*/
private $modules;
public function addModules(Module $module): self
{
if (!$this->modules->contains($module)) {
$this->modules[] = $module;
}
return $this;
}
public function removeModules(Module $module): self
{
if ($this->modules->contains($module)) {
$this->modules->removeElement($module);
}
return $this;
}
Class 模块
/**
* @var \Doctrine\Common\Collections\Collection|Formation[]
* @ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Formation", mappedBy="modules")
*/
private $formations;
public function addFormation(Formation $formation): self
{
if (!$this->formations->contains($formation)) {
$this->formations[] = $formation;
$article->addTag($this);
}
return $this;
}
public function removeFormation(Formation $formation): self
{
if ($this->formations->contains($formation)) {
$this->formations->removeElement($formation);
$formation->removeTag($this);
}
return $this;
}
尝试 1 - QueryBuilder - 加入
$this->createQueryBuilder('f')
->join('f.modules', 'm')
->select('f, m')
->getQuery()
->getResult();
我得到 [语义错误] 第 0 行,'m' 附近的第 81 列:错误:Class MarvinEntreprisesBundle\Entity\Formation 没有名为模块的关联
我尝试使用 "Modules"、"Module"、"Formations"、"Formation"、"entreprises_formation_module"(连接名称 table")
尝试 2 - QueryBuilder - leftJoin
$this->getEntityManager()
->createQueryBuilder()
->leftJoin(Module::class, 'm')
->andWhere('m.id = :id')
->setParameter('id', $formation->getId());
我得到一个错误 "No alias was set before invoking getRootAlias()".
尝试 3 - 获取="EAGER"
没有收到错误,我得到了所有 "Formation" 项,但任何 "Module" linked 都在对象中。顺便说一下,模块属性没有设置(不是空的....什么都没有)。
此时,我发现我的 "Formation" class 上没有 "getModules()"。如果我添加它,我会收到错误消息:
Return MarvinEntreprisesBundle\Entity\Formation::getModules() 的值必须是 Doctrine\Common\Collections\ArrayCollection 的实例,返回 null
一些问题
如果我在数据库中写入了 "Formation" 项、"Module" 项和 "entreprises_formation_module" link 直接项,那么不要使用 Symfony EntityManager 进行创建,设置 en刷新数据库..那改变了什么? (我还没有创建这样做的方法)
一些信息
如果我做一个 "formation->find()" 我得到
MarvinEntreprisesBundle\Entity\Formation {#1602
-id: 3
-enable: false
-publish: false
-dateToPublish: null
-status: "draft"
-modules: null
}
模块已设置但为空
如果我做一个 "module->find(x)" 我得到
MarvinEntreprisesBundle\Entity\Module {#1650
-id: 2
-enable: false
-publish: false
-dateToPublish: null
-status: "draft"
-moduleDescriptions: Doctrine\ORM\PersistentCollection {#1370
-snapshot: []
-owner: MarvinEntreprisesBundle\Entity\Module {#1650}
-association: array:15 [ …15]
-em: Doctrine\ORM\EntityManager {#1329 …11}
-backRefFieldName: "module"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#1647 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#1676
-elements: []
}
#initialized: false
}
-formations: Doctrine\ORM\PersistentCollection {#1619
-snapshot: []
-owner: MarvinEntreprisesBundle\Entity\Module {#1650}
-association: array:16 [ …16]
-em: Doctrine\ORM\EntityManager {#1329 …11}
-backRefFieldName: "modules"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#1430 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#1617
- elements: []
}
#initialized: false
}
}
队形已定!但不取。如果在 "Module" class
添加 fetch="EAGER"
@ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Formation", mappedBy="modules", fetch="EAGER")
我收到错误 通知:未定义的索引:模块
如果我回到代码中,我会反转 "mappedBy" 和 "inversedBy",Doctrine:Schema:Update 会给我不同的结果
//Class Module
@ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Formation", mappedBy="modules", fetch="EAGER")
//Class Formation
@ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Module", inversedBy="formations", fetch="EAGER")
//Doctrine:schema:update --dump-sql ==> create nothing
但是
//Class Module
@ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Formation", inversedBy="modules", fetch="EAGER")
//Class Formation
@ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Module", mappedBy="formations", fetch="EAGER")
//Doctrine:schema:update --dump-sql create
CREATE TABLE module_formation (module_id INT NOT NULL, formation_id INT NOT NULL, INDEX IDX_1A213E77AFC2B591 (module_id), INDEX IDX_1A213E775200282E (formation_id), PRIMARY KEY(module_id, formation_id)) DEFAULT CHARACTER SET UTF8 COLLATE `UTF8_unicode_ci` ENGINE = InnoDB;
在这种情况下,如果我使用 fetch="EAGER" 执行 "Module->find(x)" 我得到:
MarvinEntreprisesBundle\Entity\Module {
-id: 2
-enable: false
-publish: false
-dateToPublish: null
-status: "draft"
-moduleDescriptions: Doctrine\ORM\PersistentCollection {#895
-snapshot: array:1 [ …1]
-owner: MarvinEntreprisesBundle\Entity\Module {#900}
-association: array:15 [ …15]
-em: Doctrine\ORM\EntityManager {#527 …11}
-backRefFieldName: "module"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#788 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#897
-elements: array:1 [
0 => MarvinEntreprisesBundle\Entity\ModuleDescription {#872
-id: 2
-titre: "Stress, souffrance et mal-être au travail"
-module: MarvinEntreprisesBundle\Entity\Module {#900}
-language: "FR"
}
]
}
#initialized: true
}
-formations: Doctrine\ORM\PersistentCollection {#898
-snapshot: array:1 [ …1]
-owner: MarvinEntreprisesBundle\Entity\Module {#900}
-association: array:19 [ …19]
-em: Doctrine\ORM\EntityManager {#527 …11}
-backRefFieldName: "modules"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#631 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#865
-elements: array:1 [
0 => MarvinEntreprisesBundle\Entity\Formation {#843
-id: 1
-enable: false
-publish: false
-dateToPublish: null
-formationDescriptions: Doctrine\ORM\PersistentCollection {#867
-snapshot: array:1 [ …1]
-owner: MarvinEntreprisesBundle\Entity\Formation {#843}
-association: array:15 [ …15]
-em: Doctrine\ORM\EntityManager {#527 …11}
-backRefFieldName: "formation"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#834 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#866
-elements: array:1 [
0 => MarvinEntreprisesBundle\Entity\FormationDescription
-id: 1
-titre: "Gestion des pressions sociales"
-formation: MarvinEntreprisesBundle\Entity\Formation {#843}
-language: "FR"
}
]
}
#initialized: true
}
-status: "draft"
-modules: null
}
]
}
#initialized: true
}
}
它的工作,但如果我用 fetch="EAGER" 调用“Formation->find(1)”(Formation->find(1) 与我在之前的 Modules->find(x) 中得到的相同),我得到:
MarvinEntreprisesBundle\Entity\Formation {
-id: 1
-enable: false
-publish: false
-dateToPublish: null
-formationDescriptions: Doctrine\ORM\PersistentCollection {#1647
-snapshot: array:1 [ …1]
-owner: MarvinEntreprisesBundle\Entity\Formation {#1700}
-association: array:15 [ …15]
-em: Doctrine\ORM\EntityManager {#1330 …11}
-backRefFieldName: "formation"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#1588 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#1698
-elements: array:1 [
0 => MarvinEntreprisesBundle\Entity\FormationDescription {#1664
-id: 1
-titre: "Gestion des pressions sociales"
-formation: MarvinEntreprisesBundle\Entity\Formation {#1700}
-language: "FR"
}
]
}
#initialized: true
}
-status: "draft"
-modules: null
模块再次为空
提前谢谢大家支持我的无能
要让您的模块直接链接到您获取的对象,请在您的存储库中使用 leftJoin
:
// FormationRepository.php
public function getFormationWithModules(){
$q = $this->createQueryBuilder('f')
->leftJoin('f.modules', 'modules') <<<===
->addSelect('modules') <<== EDIT : Add addSelect row
->andWhere('modules.id = :id')
->setParameter('id', $formation->getId());
return $q->getQuery()->getResults();
}
leftJoin
只会获取链接在您的 formation.modules
中的项目
我找到了!
Class编队
/*** <===== THIS ! =====
* @var \Doctrine\Common\Collections\Collection|Module[]
* @ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Module",inversedBy="formations")
* @ORM\JoinTable(
* name="entreprises_formation_module",
* joinColumns={
* @ORM\JoinColumn(name="formation_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="module_id", referencedColumnName="id")
* }
* )
*/
private $modules;
永远不会设置属性模块,因为注释的开头有三个 *。
所以ORM和"Formation"从来没有这个属性,导致错误:Class MarvinEntreprisesBundle\Entity\Formation has no association named modules
现在我可以做一个简单的 "return $this->findAll();" 并且我得到了我的项目完全提取
而且我也可以使用@AppyGG 代码。
谢谢 AppyGG,谢谢 Vyctorya
我尝试从多对多关系中获取数据。我发现了很多关于这个主题的 videos/posts/blogs,但我无法让它工作(或理解)。我需要帮助。
太棒了!我有 "Formation" 和 "Module" class。每个 "Formation" 可以有很多 "Module" 反之亦然。
预期结果
我想获得 "Formation" array(all)/item(byId) 以及所有 "Modules" link 在“->modules”属性中编辑它。
Class阵型
/***
* @var \Doctrine\Common\Collections\Collection|Module[]
* @ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Module", inversedBy="formations")
* @ORM\JoinTable(
* name="entreprises_formation_module",
* joinColumns={
* @ORM\JoinColumn(name="formation_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="module_id", referencedColumnName="id")
* }
* )
*/
private $modules;
public function addModules(Module $module): self
{
if (!$this->modules->contains($module)) {
$this->modules[] = $module;
}
return $this;
}
public function removeModules(Module $module): self
{
if ($this->modules->contains($module)) {
$this->modules->removeElement($module);
}
return $this;
}
Class 模块
/**
* @var \Doctrine\Common\Collections\Collection|Formation[]
* @ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Formation", mappedBy="modules")
*/
private $formations;
public function addFormation(Formation $formation): self
{
if (!$this->formations->contains($formation)) {
$this->formations[] = $formation;
$article->addTag($this);
}
return $this;
}
public function removeFormation(Formation $formation): self
{
if ($this->formations->contains($formation)) {
$this->formations->removeElement($formation);
$formation->removeTag($this);
}
return $this;
}
尝试 1 - QueryBuilder - 加入
$this->createQueryBuilder('f')
->join('f.modules', 'm')
->select('f, m')
->getQuery()
->getResult();
我得到 [语义错误] 第 0 行,'m' 附近的第 81 列:错误:Class MarvinEntreprisesBundle\Entity\Formation 没有名为模块的关联
我尝试使用 "Modules"、"Module"、"Formations"、"Formation"、"entreprises_formation_module"(连接名称 table")
尝试 2 - QueryBuilder - leftJoin
$this->getEntityManager()
->createQueryBuilder()
->leftJoin(Module::class, 'm')
->andWhere('m.id = :id')
->setParameter('id', $formation->getId());
我得到一个错误 "No alias was set before invoking getRootAlias()".
尝试 3 - 获取="EAGER"
没有收到错误,我得到了所有 "Formation" 项,但任何 "Module" linked 都在对象中。顺便说一下,模块属性没有设置(不是空的....什么都没有)。
此时,我发现我的 "Formation" class 上没有 "getModules()"。如果我添加它,我会收到错误消息: Return MarvinEntreprisesBundle\Entity\Formation::getModules() 的值必须是 Doctrine\Common\Collections\ArrayCollection 的实例,返回 null
一些问题
如果我在数据库中写入了 "Formation" 项、"Module" 项和 "entreprises_formation_module" link 直接项,那么不要使用 Symfony EntityManager 进行创建,设置 en刷新数据库..那改变了什么? (我还没有创建这样做的方法)
一些信息
如果我做一个 "formation->find()" 我得到
MarvinEntreprisesBundle\Entity\Formation {#1602
-id: 3
-enable: false
-publish: false
-dateToPublish: null
-status: "draft"
-modules: null
}
模块已设置但为空
如果我做一个 "module->find(x)" 我得到
MarvinEntreprisesBundle\Entity\Module {#1650
-id: 2
-enable: false
-publish: false
-dateToPublish: null
-status: "draft"
-moduleDescriptions: Doctrine\ORM\PersistentCollection {#1370
-snapshot: []
-owner: MarvinEntreprisesBundle\Entity\Module {#1650}
-association: array:15 [ …15]
-em: Doctrine\ORM\EntityManager {#1329 …11}
-backRefFieldName: "module"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#1647 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#1676
-elements: []
}
#initialized: false
}
-formations: Doctrine\ORM\PersistentCollection {#1619
-snapshot: []
-owner: MarvinEntreprisesBundle\Entity\Module {#1650}
-association: array:16 [ …16]
-em: Doctrine\ORM\EntityManager {#1329 …11}
-backRefFieldName: "modules"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#1430 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#1617
- elements: []
}
#initialized: false
}
}
队形已定!但不取。如果在 "Module" class
添加 fetch="EAGER" @ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Formation", mappedBy="modules", fetch="EAGER")
我收到错误 通知:未定义的索引:模块
如果我回到代码中,我会反转 "mappedBy" 和 "inversedBy",Doctrine:Schema:Update 会给我不同的结果
//Class Module
@ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Formation", mappedBy="modules", fetch="EAGER")
//Class Formation
@ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Module", inversedBy="formations", fetch="EAGER")
//Doctrine:schema:update --dump-sql ==> create nothing
但是
//Class Module
@ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Formation", inversedBy="modules", fetch="EAGER")
//Class Formation
@ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Module", mappedBy="formations", fetch="EAGER")
//Doctrine:schema:update --dump-sql create
CREATE TABLE module_formation (module_id INT NOT NULL, formation_id INT NOT NULL, INDEX IDX_1A213E77AFC2B591 (module_id), INDEX IDX_1A213E775200282E (formation_id), PRIMARY KEY(module_id, formation_id)) DEFAULT CHARACTER SET UTF8 COLLATE `UTF8_unicode_ci` ENGINE = InnoDB;
在这种情况下,如果我使用 fetch="EAGER" 执行 "Module->find(x)" 我得到:
MarvinEntreprisesBundle\Entity\Module {
-id: 2
-enable: false
-publish: false
-dateToPublish: null
-status: "draft"
-moduleDescriptions: Doctrine\ORM\PersistentCollection {#895
-snapshot: array:1 [ …1]
-owner: MarvinEntreprisesBundle\Entity\Module {#900}
-association: array:15 [ …15]
-em: Doctrine\ORM\EntityManager {#527 …11}
-backRefFieldName: "module"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#788 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#897
-elements: array:1 [
0 => MarvinEntreprisesBundle\Entity\ModuleDescription {#872
-id: 2
-titre: "Stress, souffrance et mal-être au travail"
-module: MarvinEntreprisesBundle\Entity\Module {#900}
-language: "FR"
}
]
}
#initialized: true
}
-formations: Doctrine\ORM\PersistentCollection {#898
-snapshot: array:1 [ …1]
-owner: MarvinEntreprisesBundle\Entity\Module {#900}
-association: array:19 [ …19]
-em: Doctrine\ORM\EntityManager {#527 …11}
-backRefFieldName: "modules"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#631 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#865
-elements: array:1 [
0 => MarvinEntreprisesBundle\Entity\Formation {#843
-id: 1
-enable: false
-publish: false
-dateToPublish: null
-formationDescriptions: Doctrine\ORM\PersistentCollection {#867
-snapshot: array:1 [ …1]
-owner: MarvinEntreprisesBundle\Entity\Formation {#843}
-association: array:15 [ …15]
-em: Doctrine\ORM\EntityManager {#527 …11}
-backRefFieldName: "formation"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#834 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#866
-elements: array:1 [
0 => MarvinEntreprisesBundle\Entity\FormationDescription
-id: 1
-titre: "Gestion des pressions sociales"
-formation: MarvinEntreprisesBundle\Entity\Formation {#843}
-language: "FR"
}
]
}
#initialized: true
}
-status: "draft"
-modules: null
}
]
}
#initialized: true
}
}
它的工作,但如果我用 fetch="EAGER" 调用“Formation->find(1)”(Formation->find(1) 与我在之前的 Modules->find(x) 中得到的相同),我得到:
MarvinEntreprisesBundle\Entity\Formation {
-id: 1
-enable: false
-publish: false
-dateToPublish: null
-formationDescriptions: Doctrine\ORM\PersistentCollection {#1647
-snapshot: array:1 [ …1]
-owner: MarvinEntreprisesBundle\Entity\Formation {#1700}
-association: array:15 [ …15]
-em: Doctrine\ORM\EntityManager {#1330 …11}
-backRefFieldName: "formation"
-typeClass: Doctrine\ORM\Mapping\ClassMetadata {#1588 …}
-isDirty: false
#collection: Doctrine\Common\Collections\ArrayCollection {#1698
-elements: array:1 [
0 => MarvinEntreprisesBundle\Entity\FormationDescription {#1664
-id: 1
-titre: "Gestion des pressions sociales"
-formation: MarvinEntreprisesBundle\Entity\Formation {#1700}
-language: "FR"
}
]
}
#initialized: true
}
-status: "draft"
-modules: null
模块再次为空
提前谢谢大家支持我的无能
要让您的模块直接链接到您获取的对象,请在您的存储库中使用 leftJoin
:
// FormationRepository.php
public function getFormationWithModules(){
$q = $this->createQueryBuilder('f')
->leftJoin('f.modules', 'modules') <<<===
->addSelect('modules') <<== EDIT : Add addSelect row
->andWhere('modules.id = :id')
->setParameter('id', $formation->getId());
return $q->getQuery()->getResults();
}
leftJoin
只会获取链接在您的 formation.modules
我找到了!
Class编队
/*** <===== THIS ! =====
* @var \Doctrine\Common\Collections\Collection|Module[]
* @ORM\ManyToMany(targetEntity="MarvinEntreprisesBundle\Entity\Module",inversedBy="formations")
* @ORM\JoinTable(
* name="entreprises_formation_module",
* joinColumns={
* @ORM\JoinColumn(name="formation_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* @ORM\JoinColumn(name="module_id", referencedColumnName="id")
* }
* )
*/
private $modules;
永远不会设置属性模块,因为注释的开头有三个 *。
所以ORM和"Formation"从来没有这个属性,导致错误:Class MarvinEntreprisesBundle\Entity\Formation has no association named modules
现在我可以做一个简单的 "return $this->findAll();" 并且我得到了我的项目完全提取
而且我也可以使用@AppyGG 代码。
谢谢 AppyGG,谢谢 Vyctorya