我遇到了Symfony3 / doctrine2和多对多列的问题。我刚开始用它开发
是的,我看到帖子:Doctrine2: Best way to handle many-to-many with extra columns in reference table 但老实说,我不明白为什么它不能用我的代码......
我被困2天,看着谷歌(他不是我的朋友),阅读文件......我的大脑不明白......
请帮助我理解原因。
我有会员和地址实体。我想按成员或所有成员的地址提供所有地址。所以,ManyToMany在学说中。
在我的联接表上,我需要一个额外的列favorite_address
所以,我需要有3个实体:Member,Address,MemberAddress
实体成员:
class Member implements AdvancedUserInterface
{
....
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Member\MemberAddress", mappedBy="member", cascade={"all"})
* @ORM\JoinTable(name="member_address",
* joinColumns={@ORM\JoinColumn(name="member_id", referencedColumnName="id")})
*/
private $addresses;
....
public function __construct(){
$this->addresses = new ArrayCollection();
}
/**
* Add an address
* @param Address $address
*/
public function addAddress(\AppBundle\Entity\Address\Address $address)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->addresses[] = $address;
}
/**
* Remove an address
* @param Address $address
*/
public function removeAddress(\AppBundle\Entity\Address\Address $address)
{
// Ici on utilise une méthode de l'ArrayCollection, pour supprimer la catégorie en argument
$this->addresses->removeElement($address);
}
/**
* Get all addresses
* @return ArrayCollection
*/
public function getAddresses()
{
return $this->addresses;
}
实体地址:
class Address
{
....
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Member\MemberAddress", mappedBy="address", cascade={"all"})
* @ORM\JoinTable(name="member_address",
* joinColumns={@ORM\JoinColumn(name="address_id", referencedColumnName="id")})
*/
private $members;
....
/**
* Add a member
* @param Member $member
*/
public function addMember(\AppBundle\Entity\Member\Member $member)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->members[] = $member;
}
/**
* Remove a member
* @param Member $member
*/
public function removeMember(\AppBundle\Entity\Member\Member $member)
{
// Ici on utilise une méthode de l'ArrayCollection, pour supprimer la catégorie en argument
$this->members->removeElement($member);
}
/**
* Get all members
* @return ArrayCollection
*/
public function getMembers()
{
return $this->members;
}
最后一个Entity:MemberAddressReference
class MemberAddress
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/** @ORM\ManyToOne(targetEntity="AppBundle\Entity\Member\Member", inversedBy="addresses")
* @ORM\JoinColumn(name="member_id", referencedColumnName="id")
*/
protected $member;
/** @ORM\ManyToOne(targetEntity="AppBundle\Entity\Address\Address", inversedBy="members")
* @ORM\JoinColumn(name="address_id", referencedColumnName="id")
*/
protected $address;
/** @ORM\Column(type="boolean") */
protected $isFavorite;
完成,控制器
class MemberAddressController extends Controller
{
public function createAction(Request $request){
....
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$currentDate = new \DateTime("now");
$em = $this->getDoctrine()->getManager();
$address = new Address();
$memberAddress = new MemberAddress();
$address->setType($form['type']->getData());
$address->setCreated($currentDate);
$address->setModified($currentDate);
$memberAddress->setMember($member);
$memberAddress->setAddress($address);
$memberAddress->setFavorite(1);
$em->persist($member);
$em->persist($address);
$em->persist($memberAddress);
$member->addAddress($address);
$em->flush();
dump($member);
die();
}
我收到此错误:
Expected value of type "Doctrine\Common\Collections\Collection|array" for association field "AppBundle\Entity\Member\Member#$addresses", got "AppBundle\Entity\Address\Address" instead.
是的,类型不好,我理解,但为什么他不好?
public function addAddress(\AppBundle\Entity\Address\Address $address)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->addresses[] = $address;
}
addAddress取地址对象,没有?那他为什么要等阵?
请帮帮我,我疯了......
答案 0 :(得分:0)
我不了解 memberAdress 实体的目标。如果要创建OneToMany双向关系,则不需要创建第三个实体。 根据学说文件:
/** @Entity */
class Product
{
// ...
/**
* One Product has Many Features.
* @OneToMany(targetEntity="Feature", mappedBy="product")
*/
private $features;
// ...
public function __construct() {
$this->features = new ArrayCollection();
}
}
/** @Entity */
class Feature
{
// ...
/**
* Many Features have One Product.
* @ManyToOne(targetEntity="Product", inversedBy="features")
* @JoinColumn(name="product_id", referencedColumnName="id")
*/
private $product;
// ...
}
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html
如果您想使用第三个实体,则您的地址与您的会员之间不存在关系。它们只是由第三方联系在一起。 所以你应该这样做:
会员实体:
class Member implements AdvancedUserInterface
{
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Member\MemberAddress", mappedBy="member", cascade={"all"})
*/
private $addresses;
地址实体
class Address
{
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Member\MemberAddress", mappedBy="address", cascade={"all"})
*/
private $members;
如果您想要成员的所有地址,则需要创建自定义存储库以将地址表与其他两个表连接。