Symfony Doctrine:如何通过 getter 获取具有附加属性的关系数据
Symfony Doctrine: How to get Relation data with additional attributes through getters
我想开发一个由原则驱动的数据库应用程序,它应该描述以下模式。
有用户、公司和关系角色,描述用户与公司之间的关系,如 [USER X] is [ROLE X] in [COMPANY X]
。
我正在使用 symfony maker-bundle
创建我需要的实体。我将在本文末尾附上所有代码 post。
为了测试代码,我将公司、用户、角色以及它们之间的关系持久化到数据库中。我希望我可以使用 Company-Entity-Object
和生成的 getter getRelatedUsers()
获得所有相关用户的角色,但我得到一个空的 ArrayCollection
.
这就是我在 TestController
中测试获取数据的方式
#[Route('/test', name: 'test_page')]
public function index(CompanyRepository $companyRepository): Response
{
$companies = $companyRepository->findAll();
dd($companies[0]->getRelatedUsers());
}
感谢您的帮助!
User.php
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=UserRepository::class)
* @ORM\Table(name="`user`")
*/
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $fullName;
/**
* @ORM\OneToMany(targetEntity=UserCompanyRelation::class, mappedBy="user")
*/
private $relatedCompanies;
public function __construct()
{
$this->relatedCompanies = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getFullName(): ?string
{
return $this->fullName;
}
public function setFullName(string $fullName): self
{
$this->fullName = $fullName;
return $this;
}
/**
* @return Collection|UserCompanyRelation[]
*/
public function getRelatedCompanies(): Collection
{
return $this->relatedCompanies;
}
public function addRelatedCompany(UserCompanyRelation $relatedCompany): self
{
if (!$this->relatedCompanies->contains($relatedCompany)) {
$this->relatedCompanies[] = $relatedCompany;
$relatedCompany->setUser($this);
}
return $this;
}
public function removeRelatedCompany(UserCompanyRelation $relatedCompany): self
{
if ($this->relatedCompanies->removeElement($relatedCompany)) {
// set the owning side to null (unless already changed)
if ($relatedCompany->getUser() === $this) {
$relatedCompany->setUser(null);
}
}
return $this;
}
}
Company.php
<?php
namespace App\Entity;
use App\Repository\CompanyRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=CompanyRepository::class)
*/
class Company
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity=UserCompanyRelation::class, mappedBy="company")
*/
private $relatedUsers;
public function __construct()
{
$this->relatedUsers = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|UserCompanyRelation[]
*/
public function getRelatedUsers(): Collection
{
return $this->relatedUsers;
}
public function addRelatedUser(UserCompanyRelation $relatedUser): self
{
if (!$this->relatedUsers->contains($relatedUser)) {
$this->relatedUsers[] = $relatedUser;
$relatedUser->setCompany($this);
}
return $this;
}
public function removeRelatedUser(UserCompanyRelation $relatedUser): self
{
if ($this->relatedUsers->removeElement($relatedUser)) {
// set the owning side to null (unless already changed)
if ($relatedUser->getCompany() === $this) {
$relatedUser->setCompany(null);
}
}
return $this;
}
}
UserCompanyRelation.php
<?php
namespace App\Entity;
use App\Repository\UserCompanyRelationRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=UserCompanyRelationRepository::class)
*/
class UserCompanyRelation
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=UserCompanyRelationRole::class, inversedBy="userCompanyRelations")
* @ORM\JoinColumn(nullable=false)
*/
private $role;
/**
* @ORM\ManyToOne(targetEntity=Company::class, inversedBy="relatedUsers")
* @ORM\JoinColumn(nullable=false)
*/
private $company;
/**
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="relatedCompanies")
* @ORM\JoinColumn(nullable=false)
*/
private $user;
public function __construct()
{
}
public function getId(): ?int
{
return $this->id;
}
public function getRole(): ?UserCompanyRelationRole
{
return $this->role;
}
public function setRole(?UserCompanyRelationRole $role): self
{
$this->role = $role;
return $this;
}
public function getCompany(): ?Company
{
return $this->company;
}
public function setCompany(?Company $company): self
{
$this->company = $company;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
}
UserCompanyRelationRole.php
<?php
namespace App\Entity;
use App\Repository\UserCompanyRelationRoleRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=UserCompanyRelationRoleRepository::class)
*/
class UserCompanyRelationRole
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity=UserCompanyRelation::class, mappedBy="role")
*/
private $userCompanyRelations;
public function __construct()
{
$this->userCompanyRelations = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|UserCompanyRelation[]
*/
public function getUserCompanyRelations(): Collection
{
return $this->userCompanyRelations;
}
public function addUserCompanyRelation(UserCompanyRelation $userCompanyRelation): self
{
if (!$this->userCompanyRelations->contains($userCompanyRelation)) {
$this->userCompanyRelations[] = $userCompanyRelation;
$userCompanyRelation->setRole($this);
}
return $this;
}
public function removeUserCompanyRelation(UserCompanyRelation $userCompanyRelation): self
{
if ($this->userCompanyRelations->removeElement($userCompanyRelation)) {
// set the owning side to null (unless already changed)
if ($userCompanyRelation->getRole() === $this) {
$userCompanyRelation->setRole(null);
}
}
return $this;
}
}
实体之间的双向映射应该使用inversed by。参见:https://www.doctrine-project.org/projects/doctrine-orm/en/2.9/reference/association-mapping.html#many-to-many-bidirectional
我找到了解决办法。我不得不在注释属性中将获取策略修改为 EAGER
。我在company.php
中修改了relatedUsers
注解属性
<?php
namespace App\Entity;
use App\Repository\CompanyRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=CompanyRepository::class)
*/
class Company
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity=UserCompanyRelation::class, mappedBy="company", fetch="EAGER")
*/
private $relatedUsers;
public function __construct()
{
$this->relatedUsers = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|UserCompanyRelation[]
*/
public function getRelatedUsers(): Collection
{
return $this->relatedUsers;
}
public function addRelatedUser(UserCompanyRelation $relatedUser): self
{
if (!$this->relatedUsers->contains($relatedUser)) {
$this->relatedUsers[] = $relatedUser;
$relatedUser->setCompany($this);
}
return $this;
}
public function removeRelatedUser(UserCompanyRelation $relatedUser): self
{
if ($this->relatedUsers->removeElement($relatedUser)) {
// set the owning side to null (unless already changed)
if ($relatedUser->getCompany() === $this) {
$relatedUser->setCompany(null);
}
}
return $this;
}
}
我想开发一个由原则驱动的数据库应用程序,它应该描述以下模式。
有用户、公司和关系角色,描述用户与公司之间的关系,如 [USER X] is [ROLE X] in [COMPANY X]
。
我正在使用 symfony maker-bundle
创建我需要的实体。我将在本文末尾附上所有代码 post。
为了测试代码,我将公司、用户、角色以及它们之间的关系持久化到数据库中。我希望我可以使用 Company-Entity-Object
和生成的 getter getRelatedUsers()
获得所有相关用户的角色,但我得到一个空的 ArrayCollection
.
这就是我在 TestController
#[Route('/test', name: 'test_page')]
public function index(CompanyRepository $companyRepository): Response
{
$companies = $companyRepository->findAll();
dd($companies[0]->getRelatedUsers());
}
感谢您的帮助!
User.php
<?php
namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=UserRepository::class)
* @ORM\Table(name="`user`")
*/
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $fullName;
/**
* @ORM\OneToMany(targetEntity=UserCompanyRelation::class, mappedBy="user")
*/
private $relatedCompanies;
public function __construct()
{
$this->relatedCompanies = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getFullName(): ?string
{
return $this->fullName;
}
public function setFullName(string $fullName): self
{
$this->fullName = $fullName;
return $this;
}
/**
* @return Collection|UserCompanyRelation[]
*/
public function getRelatedCompanies(): Collection
{
return $this->relatedCompanies;
}
public function addRelatedCompany(UserCompanyRelation $relatedCompany): self
{
if (!$this->relatedCompanies->contains($relatedCompany)) {
$this->relatedCompanies[] = $relatedCompany;
$relatedCompany->setUser($this);
}
return $this;
}
public function removeRelatedCompany(UserCompanyRelation $relatedCompany): self
{
if ($this->relatedCompanies->removeElement($relatedCompany)) {
// set the owning side to null (unless already changed)
if ($relatedCompany->getUser() === $this) {
$relatedCompany->setUser(null);
}
}
return $this;
}
}
Company.php
<?php
namespace App\Entity;
use App\Repository\CompanyRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=CompanyRepository::class)
*/
class Company
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity=UserCompanyRelation::class, mappedBy="company")
*/
private $relatedUsers;
public function __construct()
{
$this->relatedUsers = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|UserCompanyRelation[]
*/
public function getRelatedUsers(): Collection
{
return $this->relatedUsers;
}
public function addRelatedUser(UserCompanyRelation $relatedUser): self
{
if (!$this->relatedUsers->contains($relatedUser)) {
$this->relatedUsers[] = $relatedUser;
$relatedUser->setCompany($this);
}
return $this;
}
public function removeRelatedUser(UserCompanyRelation $relatedUser): self
{
if ($this->relatedUsers->removeElement($relatedUser)) {
// set the owning side to null (unless already changed)
if ($relatedUser->getCompany() === $this) {
$relatedUser->setCompany(null);
}
}
return $this;
}
}
UserCompanyRelation.php
<?php
namespace App\Entity;
use App\Repository\UserCompanyRelationRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=UserCompanyRelationRepository::class)
*/
class UserCompanyRelation
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity=UserCompanyRelationRole::class, inversedBy="userCompanyRelations")
* @ORM\JoinColumn(nullable=false)
*/
private $role;
/**
* @ORM\ManyToOne(targetEntity=Company::class, inversedBy="relatedUsers")
* @ORM\JoinColumn(nullable=false)
*/
private $company;
/**
* @ORM\ManyToOne(targetEntity=User::class, inversedBy="relatedCompanies")
* @ORM\JoinColumn(nullable=false)
*/
private $user;
public function __construct()
{
}
public function getId(): ?int
{
return $this->id;
}
public function getRole(): ?UserCompanyRelationRole
{
return $this->role;
}
public function setRole(?UserCompanyRelationRole $role): self
{
$this->role = $role;
return $this;
}
public function getCompany(): ?Company
{
return $this->company;
}
public function setCompany(?Company $company): self
{
$this->company = $company;
return $this;
}
public function getUser(): ?User
{
return $this->user;
}
public function setUser(?User $user): self
{
$this->user = $user;
return $this;
}
}
UserCompanyRelationRole.php
<?php
namespace App\Entity;
use App\Repository\UserCompanyRelationRoleRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=UserCompanyRelationRoleRepository::class)
*/
class UserCompanyRelationRole
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity=UserCompanyRelation::class, mappedBy="role")
*/
private $userCompanyRelations;
public function __construct()
{
$this->userCompanyRelations = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|UserCompanyRelation[]
*/
public function getUserCompanyRelations(): Collection
{
return $this->userCompanyRelations;
}
public function addUserCompanyRelation(UserCompanyRelation $userCompanyRelation): self
{
if (!$this->userCompanyRelations->contains($userCompanyRelation)) {
$this->userCompanyRelations[] = $userCompanyRelation;
$userCompanyRelation->setRole($this);
}
return $this;
}
public function removeUserCompanyRelation(UserCompanyRelation $userCompanyRelation): self
{
if ($this->userCompanyRelations->removeElement($userCompanyRelation)) {
// set the owning side to null (unless already changed)
if ($userCompanyRelation->getRole() === $this) {
$userCompanyRelation->setRole(null);
}
}
return $this;
}
}
实体之间的双向映射应该使用inversed by。参见:https://www.doctrine-project.org/projects/doctrine-orm/en/2.9/reference/association-mapping.html#many-to-many-bidirectional
我找到了解决办法。我不得不在注释属性中将获取策略修改为 EAGER
。我在company.php
relatedUsers
注解属性
<?php
namespace App\Entity;
use App\Repository\CompanyRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass=CompanyRepository::class)
*/
class Company
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\OneToMany(targetEntity=UserCompanyRelation::class, mappedBy="company", fetch="EAGER")
*/
private $relatedUsers;
public function __construct()
{
$this->relatedUsers = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* @return Collection|UserCompanyRelation[]
*/
public function getRelatedUsers(): Collection
{
return $this->relatedUsers;
}
public function addRelatedUser(UserCompanyRelation $relatedUser): self
{
if (!$this->relatedUsers->contains($relatedUser)) {
$this->relatedUsers[] = $relatedUser;
$relatedUser->setCompany($this);
}
return $this;
}
public function removeRelatedUser(UserCompanyRelation $relatedUser): self
{
if ($this->relatedUsers->removeElement($relatedUser)) {
// set the owning side to null (unless already changed)
if ($relatedUser->getCompany() === $this) {
$relatedUser->setCompany(null);
}
}
return $this;
}
}