我与Coupon ManyToMany有关系。 用户有许多优惠券,并且优惠券可能属于许多用户。 当我调用方法$ coupon-> getUsers()时,我得到了优惠券(PersistentCollection)。 当我调用方法$ user-> getCoupon()时,我得到了用户(PersistentCollection)。
用户实体:
/**
* @ORM\ManyToMany(targetEntity="App\Entity\Coupon", inversedBy="users")
*/
private $coupon;
public function __construct()
{
$this->coupon = new ArrayCollection();
}
/**
* @return Collection|Coupon[]
*/
public function getCoupon(): Collection
{
return $this->coupon;
}
public function addCoupon(Coupon $coupon): self
{
if (!$this->coupon->contains($coupon)) {
$this->coupon[] = $coupon;
}
return $this;
}
public function removeCoupon(Coupon $coupon): self
{
if ($this->coupon->contains($coupon)) {
$this->coupon->removeElement($coupon);
}
return $this;
}
优惠券实体:
/**
* @ORM\ManyToMany(targetEntity="App\Entity\User", mappedBy="coupon")
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* @return Collection|User[]
*/
public function getUsers(): Collection
{
return $this->users;
}
public function addUser(User $user): self
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
$user->addCoupon($this);
}
return $this;
}
public function removeUser(User $user): self
{
if ($this->users->contains($user)) {
$this->users->removeElement($user);
$user->removeCoupon($this);
}
return $this;
}
运行此代码时:
namespace App\Controller;
use App\Entity\Coupon;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
class TestController extends AbstractController
{
/**
* @Route("/test", name="test")
*/
public function index()
{
$coupon = $this->getDoctrine()->getRepository(Coupon::class)->find(1);
dump($coupon->getUsers());die;
}
}
我得到: screenshot
为什么我得到优惠券而不是用户列表?
答案 0 :(得分:1)
除了Jakumi所写的内容之外,您还可以在控制器中执行
$coupon = $this->getDoctrine()->getRepository(Coupon::class)->find(1);
$users = $coupon->getUsers();
$users->initialize();
现在,当您dump($users)
时集合不应为空。
此外,我认为您的映射错误。在您的多对多关系中,User
是拥有方,而Coupon
是相反方,但是public function addUser(User $user)
实体中的Coupon
是{ {3}}。您应该更改边(将mappedBy
中的Coupon
更改为inversedBy
,并在User
中进行相反的更改),或确保User
这样做:
public function addCoupon(Coupon $coupon): self
{
if (!$this->coupon->contains($coupon)) {
$coupon->addUser($this);
$this->coupon[] = $coupon;
}
return $this;
}
而Coupon
会这样做:
public function addUser(User $user): self
{
if (!$this->users->contains($user)) {
$this->users[] = $user;
}
return $this;
}
当然,应该相应地处理removeUser
和removeCoupon
方法。
答案 1 :(得分:0)
PersistentCollection
从概念上讲应该像数组一样工作,并且是实现延迟加载(默认)的原则。有某些操作将触发从数据库加载集合(例如遍历集合)。在此之前,它的属性initialized
将为false(如您的屏幕截图所示)
ManyToMany和OneToMany应该始终实现为ArrayCollection(或某些其他集合,例如PersistentCollection),并且不应泄漏到外部。而是调用->toArray()
(或我经常忘记的->asArray()
)来返回它们(因此,分别在getUsers()
或getCoupons()
内部)。在实体内部,您可以foreach
上方的PersistentCollection
上。
如果将ManyToMany标记为fetch
为EAGER
,它将立即被加载,但这可能会影响性能...
并且Collection拥有对其所属对象的引用,因此您本身并没有得到Coupon,而是获得了一个仍引用其所有者; o)