当Doctrine不允许我将复合主键与另一个实体的外键关联时,如何对ER图建模?

时间:2016-09-08 17:42:37

标签: php mysql symfony doctrine-orm doctrine

我正在尝试模拟

之间的ManyToOne关系
  1. product_pricenamecategory_pricename
  2. price_historyproduct_pricename,如下图所示:
  3. enter image description here

    如何?

    我在哪里

    我注意到此ER图包含 composite foreign key

      

    我说的是关键字为product_pricename

    的表(category_pricename_category_id, category_pricename_pricename_id)

    是另一个实体主键的一部分

      

    我正在谈论category_pricename (category_id, pricename_id)

    的PRIMARY KEY

    MySQL完全没问题。但是当我尝试在Doctrine中对此进行建模时,我得到一个错误:

    [Doctrine\ORM\Mapping\MappingException]
    It is not possible to map entity 'CategoryPricename' with a composite 
    primary key as part of the primary key of another entity
    'ProductPricename#categoryPricename'.
    

    到目前为止,我还没有想象出在Doctrine中这样做的正确方法。

    我想我可以为实体product_pricenamecategory_pricename引入代理PRIMARY KEY并重新建模我的表格。但这会是一种方法吗?

    相关代码

    class CategoryPricename
    {
    
        /**
         * @Id @ManyToOne(targetEntity="Category")
         * @JoinColumn(name="category_id", referencedColumnName="id", nullable=false)
         *
         * @var Category
         */
        private $category;
    
        /**
         * @Id @ManyToOne(targetEntity="Pricename")
         * @JoinColumn(name="pricename_id", referencedColumnName="id", nullable=false)
         *
         * @var Pricename
         */
        private $pricename;
    }
    
    class ProductPricename
    {
    
        /**
         * @Id @ManyToOne(targetEntity="Product")
         * @JoinColumn(name="product_id", referencedColumnName="id", nullable=false)
         *
         * @var Product
         */
        private $product;
    
        /**
         * Note:  I shortened the column names for my code
         * by removing "category_pricename_" prefix for brevity
         * as reflected in JoinColumn's name attributes
         *
         * @Id
         * @ManyToOne(targetEntity="CategoryPricename")
         * @JoinColumns({
         *   @JoinColumn(name="category_id", referencedColumnName="category_id", nullable=false),
         *   @JoinColumn(name="pricename_id", referencedColumnName="pricename_id", nullable=false)
         * })
         *
         * @var CategoryPricename
         */
        private $categoryPricename;
    }
    

    自然与代理键

    似乎与Doctrine一样,我必须在表格中使用代理键来使我的设计符合Doctrine的限制。

    OR

    我可以使用mysqli并使用自然键(现在在ER图的一些表中)

    我的一部分...我去哪条路线,代理(学说)或自然(mysqli)

1 个答案:

答案 0 :(得分:0)

对Doctrine中更复杂关系的建模需要:

  1. 将所有关系建模为实体。让每个这样的关系实体都有一个代理id主键。
  2. 而不是ManyToMany关系,而不是每一方使用ManyToOne。
  3. 要使上述工作正常,您可能需要将表的结构更改为没有复合主键的位置。这是因为Doctrine允许复合主键与外部ID相关联。这是一个限制。使用此限制意味着拥有更多的代理键和更少的自然键,这意味着有更多的表连接,即查询price_history

    替代方法是使用mysqli或PDO。

    替代方法是不使用Doctrine。根据需要设置表格,然后使用mysqliPDO。我之所以选择这条路是因为我的设计我想要使用ER Design和DBMS的全部功能而不必处理很多表连接。