学说 - 如何建立反向关系?

时间:2015-05-20 11:02:53

标签: php symfony doctrine-orm dql

在symfony中,我从已创建的数据库中创建了两个实体。我使用了symfony控制台中的以下命令:

php app/console doctrine:mapping:import --force IDFrontendBundle xml
php app/console doctrine:mapping:convert annotation ./src
php app/console doctrine:generate:entities IDFrontendBundle

生成我的两个实体以及我遇到问题的实体如下

use Doctrine\ORM\Mapping as ORM;

/**
 * ProviderRate
 *
 * @ORM\Table(name="provider_rate", indexes={@ORM\Index(name="fk_proveedor_has_producto_compra_producto_compra1_idx", columns={"product_id"}), @ORM\Index(name="fk_id_tarifa_proveedor_id_moneda1_idx", columns={"currency_id"}), @ORM\Index(name="IDX_3A645C45A53A8AA", columns={"provider_id"})})
 * @ORM\Entity(repositoryClass="IDavid\FrontendBundle\Entity\ProviderRateRepository")
 */
class ProviderRate
{
/**
 * @var string
 *
 * @ORM\Column(name="reference", type="string", length=45, nullable=false)
 */
private $reference;

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=45, nullable=false)
 */
private $name;

/**
 * @var string
 *
 * @ORM\Column(name="description", type="string", length=255, nullable=false)
 */
private $description;

/**
 * @var integer
 *
 * @ORM\Column(name="amount_per_unit", type="integer", nullable=true)
 */
private $amountPerUnit;

/**
 * @var string
 *
 * @ORM\Column(name="unit_price", type="decimal", precision=25, scale=3, nullable=false)
 */
private $unitPrice;

/**
 * @var string
 *
 * @ORM\Column(name="discount", type="decimal", precision=25, scale=3, nullable=false)
 */
private $discount;

/**
 * @var \IDavid\FrontendBundle\Entity\Providers
 *
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="NONE")
 * @ORM\OneToOne(targetEntity="IDavid\FrontendBundle\Entity\Providers")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="provider_id", referencedColumnName="id")
 * })
 */
private $provider;

/**
 * @var \IDavid\FrontendBundle\Entity\Products
 *
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="NONE")
 * @ORM\OneToOne(targetEntity="IDavid\FrontendBundle\Entity\Products")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 * })
 */
private $product;

/**
 * @var \IDavid\FrontendBundle\Entity\Currencies
 *
 * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Currencies")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="currency_id", referencedColumnName="id")
 * })
 */
private $currency;

use Doctrine\ORM\Mapping as ORM;

/**
 * Products
 *
 * @ORM\Table(name="products", uniqueConstraints={@ORM\UniqueConstraint(name="id_producto_UNIQUE", columns={"id"})}, indexes={@ORM\Index(name="fk_id_productos_id_categorias1_idx", columns={"category_id"}), @ORM\Index(name="fk_id_productos_id_producto_tipo1_idx", columns={"type"}), @ORM\Index(name="fk_id_productos_id_moneda1_idx", columns={"currency_id"})})
 * @ORM\Entity(repositoryClass="IDavid\FrontendBundle\Entity\ProductsRepository")
 */
class Products
{
    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=45, nullable=false)
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="string", length=255, nullable=false)
     */
    private $description;

    /**
     * @var string
     *
     * @ORM\Column(name="code", type="string", length=45, nullable=false)
     */
    private $code;

    /**
     * @var string
     *
     * @ORM\Column(name="description_long", type="text", nullable=false)
     */
    private $descriptionLong;

    /**
     * @var integer
     *
     * @ORM\Column(name="amount_per_unit", type="integer", nullable=false)
     */
    private $amountPerUnit;

    /**
     * @var string
     *
     * @ORM\Column(name="weight", type="decimal", precision=11, scale=3, nullable=false)
     */
    private $weight;

    /**
     * @var string
     *
     * @ORM\Column(name="web", type="string", length=100, nullable=false)
     */
    private $web;

    /**
     * @var boolean
     *
     * @ORM\Column(name="isActive", type="boolean", nullable=false)
     */
    private $isactive;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="createdtime", type="datetime", nullable=false)
     */
    private $createdtime;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="modifiedtime", type="datetime", nullable=false)
     */
    private $modifiedtime;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="deletedtime", type="datetime", nullable=true)
     */
    private $deletedtime;

    /**
     * @var boolean
     *
     * @ORM\Column(name="isDeleted", type="boolean", nullable=false)
     */
    private $isdeleted;

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var \IDavid\FrontendBundle\Entity\Categories
     *
     * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Categories")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="category_id", referencedColumnName="id")
     * })
     */
    private $category;

    /**
     * @var \IDavid\FrontendBundle\Entity\ProductTypes
     *
     * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\ProductTypes")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="type", referencedColumnName="id")
     * })
     */
    private $type;

    /**
     * @var \IDavid\FrontendBundle\Entity\Currencies
     *
     * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Currencies")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="currency_id", referencedColumnName="id")
     * })
     */
    private $currency;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Sets", inversedBy="product")
     * @ORM\JoinTable(name="products_sets",
     *   joinColumns={
     *     @ORM\JoinColumn(name="product_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="set_id", referencedColumnName="id")
     *   }
     * )
     */
    private $set;

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Products", mappedBy="productParentid")
 */
private $product;

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Documents", inversedBy="product")
 * @ORM\JoinTable(name="product_attachments",
 *   joinColumns={
 *     @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 *   },
 *   inverseJoinColumns={
 *     @ORM\JoinColumn(name="document_id", referencedColumnName="id")
 *   }
 * )
 */
private $document;

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="IDavid\FrontendBundle\Entity\Images", inversedBy="product")
 * @ORM\JoinTable(name="products_images",
 *   joinColumns={
 *     @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 *   },
 *   inverseJoinColumns={
 *     @ORM\JoinColumn(name="image_id", referencedColumnName="id")
 *   }
 * )
 */
private $image;

 /**
     * Constructor
     */
    public function __construct()
    {
        $this->set = new \Doctrine\Common\Collections\ArrayCollection();
        $this->product = new \Doctrine\Common\Collections\ArrayCollection();
        $this->document = new \Doctrine\Common\Collections\ArrayCollection();
        $this->image = new \Doctrine\Common\Collections\ArrayCollection();
        $this->providerRate = new \Doctrine\Common\Collections\ArrayCollection();
    }

我尝试创建一个新变量,将两个表以相反的顺序连接到产品类

/**
 * @ORM\OneToMany(targetEntity="IDavid\FrontendBundle\Entity\ProviderRate", inversedBy="product")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="id", referencedColumnName="product_id")
 * })
 */
private $providerRate;

但是当我进行DQL查询时,symfony告诉我没有关联。 有没有办法做到这一点?

$dql = "SELECT p, pr FROM IDFrontendBundle:Products p
                        JOIN p.providerRate pr";
$query = $this->getEntityManager()->createQuery($dql);

1 个答案:

答案 0 :(得分:2)

你们的关系基数是不同的。

ProviderRate -> Product (OneToOne)
Product -> ProviderRate (OneToMany)

因此,它不会起作用。 OneToOne双方都应该OneToMany应该与ManyToOne配对。

我假设以下内容:

  • 一个Product可以有多个ProviderRate个。 这是正确的吗?

如果是这样,您需要:

ProviderRate类

/**
 * @var \IDavid\FrontendBundle\Entity\Products
 *
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="NONE")
 * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Products", mappedBy="providerRate")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 * })
 */
private $product;

产品类

/**
 * @ORM\OneToMany(targetEntity="IDavid\FrontendBundle\Entity\ProviderRate", inversedBy="product")
 */
private $providerRate;

正如您所看到的,一旦您在关系中的任何一方声明@JoinColums,就不需要在另一方指定一个。{p}}。此外,inversedBy应与mappedBy匹配。

这有帮助吗?

修改

更改mappedBy和inversedBy属性顺序。

ProviderRate类

/**
 * @var \IDavid\FrontendBundle\Entity\Products
 *
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="NONE")
 * @ORM\ManyToOne(targetEntity="IDavid\FrontendBundle\Entity\Products", inversedBy="providerRate")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 * })
 */
private $product;

产品类

/**
 * @ORM\OneToMany(targetEntity="IDavid\FrontendBundle\Entity\ProviderRate", mappedBy="product")
 */
private $providerRate;