Symfony(Doctrine)2:实体ManyToMany与自身的关系

时间:2014-05-21 14:06:25

标签: php entity-framework symfony doctrine-orm doctrine

我有一个实体“产品”。产品可以是“包”(布尔值),然后由产品组成。产品可以是许多包的一部分。因此,我需要在Product中映射ManyToMany关系,这样我就可以在带有“package_id”和“product_id”的映射表中使用$ packageProducts。

如何在“Product”实体中定义ManyToMany关系以映射到自身?我知道你需要定义你的连接表,你需要mapColumn和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”。我需要将其作为“package_products”,其字段为“product_id”,“package_id”。我如何在ORM中定义它?

4 个答案:

答案 0 :(得分:0)

在同一个班级:

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

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

答案 1 :(得分:0)

这就是答案:

/**
 * @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 =&#34;&#34;的那个)。

答案 2 :(得分:0)

您可以使用另一个实体创建两个实现OneTOMany,而不是创建一个关系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;

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;
    }

答案 3 :(得分:0)

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

F12