繁体   English   中英

Symfony(理论)2:实体与自己之间的多对多关系

[英]Symfony (Doctrine) 2: Entity ManyToMany Relationship with itself

我有一个实体“产品”。 产品可以是“包装”(布尔),然后由“产品”组成。 产品可以是许多包装的一部分。 因此,我需要在Product与其自身之间映射一个ManyToMany关系,以便在具有“ package_id”和“ product_id”的映射表中具有$ packageProducts。

如何在“产品”实体中定义ManyToMany关系以映射到自身? 我知道您需要定义您的联接表,并且您已映射了column和inverseColumn,但是我不知道确切如何执行此操作。

当前产品实体(尚未包括ManyToMany映射):

<?php

namespace LittleGiant\PortalBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use JMS\Serializer\Annotation as Ser;
use Gedmo\Mapping\Annotation as Gedmo;

/**
 * Product
 *
 * @ORM\Entity
 * @ORM\Table(name="products")
 * @Ser\ExclusionPolicy("all")
 */
class Product
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @Ser\Expose
     */
    protected $id;

    /**
     * @var boolean
     *
     * @ORM\Column(name="package", type="boolean")
     * @Ser\Expose
     */
    protected $package;

    /**
     * @var boolean
     *
     * @ORM\Column(name="active", type="boolean")
     * @Ser\Expose
     */
    protected $active;

    /**
     * @var string
     *
     * @ORM\Column(name="product_range", type="string", length=32)
     * @Ser\Expose
     */
    protected $range;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=128)
     * @Ser\Expose
     */
    protected $name;

    /**
     * @var text
     *
     * @ORM\Column(name="description", type="text")
     * @Ser\Expose
     */
    protected $description;

    /**
     * @var File
     * 
     * @ORM\OneToOne(targetEntity="LittleGiant\PortalBundle\Entity\File", cascade={"remove","persist"})
     * @Ser\Expose
     **/
    protected $displayImage;

    /**
     * @var float
     *
     * @ORM\Column(name="price", type="float")
     * @Ser\Expose
     */
    protected $price;

    /**
     * @var Deliverable[]
     * 
     * @ORM\OneToMany(targetEntity="LittleGiant\PortalBundle\Entity\Deliverable", mappedBy="product", cascade={"remove"})
     **/
    protected $deliverables;
}

编辑:当我将以下内容添加到我的产品实体时

/**
 * @var Product[]
 * 
 * @ORM\ManyToMany(targetEntity="LittleGiant\PortalBundle\Entity\Product", mappedBy="packageProducts")
 **/
protected $packages;

/**
 * @var Product[]
 * 
 * @ORM\ManyToMany(targetEntity="LittleGiant\PortalBundle\Entity\Product", inversedBy="packages")
 **/
protected $packageProducts;

我得到带有单个字段“ product_id”的映射表“ product_product”。 我需要将其作为具有字段“ product_id”,“ package_id”的“ package_products”。 我如何在ORM中定义它?

在同一个班:

/**
 * @ORM\ManyToMany(targetEntity="Product", inversedBy="packages")
 */
private $package;

/**
 * @ORM\ManyToMany(targetEntity="Product", mappedBy="package")
 */
private $packages;

这是答案:

/**
 * @var Product[]
 * 
 * @ORM\ManyToMany(targetEntity="LittleGiant\PortalBundle\Entity\Product", mappedBy="packageProducts")
 **/
protected $packages;

/**
 * @var Product[]
 * 
 * @ORM\ManyToMany(targetEntity="LittleGiant\PortalBundle\Entity\Product", inversedBy="packages")
 * @ORM\JoinTable(name="package_products",
 *      joinColumns={@ORM\JoinColumn(name="product_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="package_id", referencedColumnName="id")}
 *      )
 * @Ser\Expose()
 **/
protected $packageProducts;

您将在要进行映射的属性上添加JoinTable信息(即:上面带有inversedBy =“”的属性)。

无需创建一个关系ManyToMany,您可以与另一个实体创建两个实境OneTOMany。

<?php 
 namespace LittleGiant\PortalBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use JMS\Serializer\Annotation as Ser;
use Gedmo\Mapping\Annotation as Gedmo;

use LittleGiant\PortalBundle\Entity\Product;

class ProductPackage{
   /**
 *
 * @ORM\Id
 *@ORM\ManyToOne(targetEntity="LittleGiant\PortalBundle\Entity\Product", inversedBy="packages")
 */
private $package;

  /**
 *
 * @ORM\Id
 *@ORM\ManyToOne(targetEntity="LittleGiant\PortalBundle\Entity\Product", inversedBy="products")
 */
private $product;


public function setProduct(Product $product){
    $this->product = $product;
    $product->setProduct($this);
}

public function getProduct(){
    return $this->product;
}

public function setPackage(Product $package){
    $this->package = $package;
    $package->setPackage($this);
}

public function getPackage(){
    return $this->Package;
}

 }
?>

-然后将以下内容添加到产品实体:

    use LittleGiant\PortalBundle\Entity\ProductPackage;// in the use declaration section      
    /**
     *
     *@ORM\OneToMany(targetEntity="LittleGiant\PortalBundle\Entity\ProductPackage", mappedBy="product", cascade={"remove"})
     */

     private $products;
   /**
     *
     *@ORM\OneToMany(targetEntity="LittleGiant\PortalBundle\Entity\ProductPackage", mappedBy="package", cascade={"remove"})
     */

     private $packages;
    public function getProducts(){
        return $this->products;
    }
    public function setProducs(ProductPackage $pp){
        $this->products[] = $pp;
    }
 public function getPackages(){
        return $this->package;
    }
    public function setPackage(ProductPackage $pp){
        $this->packages[] = $pp;
    }

参考文档(请参阅http://docs.doctrine-project.org/en/latest/reference/association-mapping.html#many-to-many-self-referencing ):我必须编辑“ getFriendsWithMe”为所有用户获取朋友的方法(添加了朋友的原始用户,反之亦然:用户的“新”朋友也应将原始用户显示为朋友):

public function getFriendsWithMe()
{
    return new ArrayCollection(
        array_merge(array_merge($this->friendsWithMe->toArray(), $this->myFriends->toArray()))
    );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM