我对Symfony3/doctrine2和多对多的额外列有问题。我刚开始用它开发
是的,我看到了帖子:Doctrine2:在引用表中使用额外列处理多对多的最佳方法但老实说,我不明白为什么它不适用于我的代码。。。
我被困了两天,在谷歌上看(他不是我的朋友),阅读文档。。。我的大脑不明白。。。
请帮我弄清楚原因。
问题
我有成员和地址实体。我想按议员或按议员的地址列出所有议员的地址。所以,学说中的ManyToMany。在我的联接表上,我需要有一个额外的列favorite_address
所以,我需要有3个实体:会员,地址,会员地址
实体成员:
class Member implements AdvancedUserInterface
{
....
/**
* @ORMOneToMany(targetEntity="AppBundleEntityMemberMemberAddress", mappedBy="member", cascade={"all"})
* @ORMJoinTable(name="member_address",
* joinColumns={@ORMJoinColumn(name="member_id", referencedColumnName="id")})
*/
private $addresses;
....
public function __construct(){
$this->addresses = new ArrayCollection();
}
/**
* Add an address
* @param Address $address
*/
public function addAddress(AppBundleEntityAddressAddress $address)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->addresses[] = $address;
}
/**
* Remove an address
* @param Address $address
*/
public function removeAddress(AppBundleEntityAddressAddress $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
{
....
/**
* @ORMOneToMany(targetEntity="AppBundleEntityMemberMemberAddress", mappedBy="address", cascade={"all"})
* @ORMJoinTable(name="member_address",
* joinColumns={@ORMJoinColumn(name="address_id", referencedColumnName="id")})
*/
private $members;
....
/**
* Add a member
* @param Member $member
*/
public function addMember(AppBundleEntityMemberMember $member)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->members[] = $member;
}
/**
* Remove a member
* @param Member $member
*/
public function removeMember(AppBundleEntityMemberMember $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;
}
最后一个实体:MemberAddressReference
class MemberAddress
{
/**
* @ORMId
* @ORMColumn(type="integer")
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;
/** @ORMManyToOne(targetEntity="AppBundleEntityMemberMember", inversedBy="addresses")
* @ORMJoinColumn(name="member_id", referencedColumnName="id")
*/
protected $member;
/** @ORMManyToOne(targetEntity="AppBundleEntityAddressAddress", inversedBy="members")
* @ORMJoinColumn(name="address_id", referencedColumnName="id")
*/
protected $address;
/** @ORMColumn(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 "DoctrineCommonCollectionsCollection|array" for association field "AppBundleEntityMemberMember#$addresses", got "AppBundleEntityAddressAddress" instead.
是的,类型不好,我理解,但为什么他不好?
public function addAddress(AppBundleEntityAddressAddress $address)
{
// Ici, on utilise l'ArrayCollection vraiment comme un tableau
$this->addresses[] = $address;
}
addAddress获取Address对象,否?那他为什么在等阵列呢?
请帮帮我,我快疯了。。。
我不理解您的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
{
/**
* @ORMOneToMany(targetEntity="AppBundleEntityMemberMemberAddress", mappedBy="member", cascade={"all"})
*/
private $addresses;
地址实体
class Address
{
/**
* @ORMOneToMany(targetEntity="AppBundleEntityMemberMemberAddress", mappedBy="address", cascade={"all"})
*/
private $members;
如果您想要一个成员的所有地址,则需要创建一个自定义存储库来将您的地址表和另外两个表连接起来。