2013-03-25 78 views
81

(對不起,我不連貫的問題:我試圖回答一些問題,因爲我在寫這篇文章,但在這裏它是:)學說2和許多一對多連接表的額外字段

我試圖創建一個在鏈接表內具有多對多關係的數據庫模型,但是每個鏈接也有一個值,在這種情況下是一個庫存表。 (這是我遇到的更多問題的一個基本示例,但我認爲在繼續之前,我會先測試它)。

Database model for a basic multi-store, multi-product store-keeping system

我用exportmwb生成兩個實體的商店和商品的這個簡單的例子,接下來都會顯示出來。

但是,現在的問題是我無法弄清楚如何使用Doctrine來訪問stock.amount值(signed int,因爲它可以是負數)。此外,當我嘗試使用學說的ORM創建表:架構工具:創建功能

the database layout as it is seen from HeidiSQL

這收穫的只是兩個實體和三個表,一個作爲一個鏈接表而不值和兩個數據表,如多對多關係本身不是實體,因此我只能將Product和Store作爲實體。

因此,在邏輯上,我嘗試改變我的數據庫模型,以便將庫存作爲一個單獨的表格與存儲和產品的關係。我還改寫了字段名只是爲了能夠排除作爲問題的根源:

changed database layout

那麼什麼我發現了,我仍然沒有得到股票的實體......和數據庫本身沒有'金額'字段。

我真的需要能夠將這些商店和產品綁定在一個庫存表中(除此之外)...所以只需將產品添加到產品本身不是一種選擇。

[email protected]:/var/www/test/library# php doctrine.php orm:info 
Found 2 mapped entities: 
[OK] Entity\Product 
[OK] Entity\Store 

當我創建數據庫時,它仍然不給我在庫存表右邊字段:

the database layout as it is seen from HeidiSQL

所以,在這裏尋找一些東西,我發現,多對多連接不是實體,因此不能具有值。所以我試着將它改成與其他人有關係的單獨表格,但它仍然無效。

我在這裏做錯了什麼?

+0

好吧,我發現一對夫婦的提及,指出這是不可能有不少一對多使用Doctrine連接,與意見建議,以防止這些關係..但什麼如果你真的停留在我原來的問題中描述的那種情況下? 我有一個完整的數據庫,與Magento兼容,完全依賴於多對多的關係。 所以基本上我被告知「學習ORM不能處理多對多,不要使用它」?? – 2013-03-25 15:13:12

+0

另請參見[Doctrine2:在參考表中處理多對多列的最佳方法](http://stackoverflow.com/questions/3542243/doctrine2-best-way-to-handle-many-to-many -with-extra-columns-in-reference-table) – Ben 2013-10-03 13:45:14

+2

如果我可以用你的努力來解釋我在這樣一個很好的方式中確切地想知道的話,會給你100分:-) – 2014-03-21 20:06:38

回答

125

與附加價值一個多-to-many關聯是不是多到很多,但確實是一個新的實體,因爲它現在有一個標識符(這兩個關係的連接實體)和值。

這也是爲什麼許多-to-many關聯是如此罕見:你傾向於存儲在其中的附加屬性,如sortingamount

什麼你可能需要的是類似以下的(我由這兩種關係是雙向的,考慮將他們設爲單向)中的至少一個:

產品:

namespace Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** @ORM\Table(name="product") @ORM\Entity() */ 
class Product 
{ 
    /** @ORM\Id() @ORM\Column(type="integer") */ 
    protected $id; 

    /** ORM\Column(name="product_name", type="string", length=50, nullable=false) */ 
    protected $name; 

    /** @ORM\OneToMany(targetEntity="Entity\Stock", mappedBy="product") */ 
    protected $stockProducts; 
} 

商店:

namespace Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** @ORM\Table(name="store") @ORM\Entity() */ 
class Store 
{ 
    /** @ORM\Id() @ORM\Column(type="integer") */ 
    protected $id; 

    /** ORM\Column(name="store_name", type="string", length=50, nullable=false) */ 
    protected $name; 

    /** @ORM\OneToMany(targetEntity="Entity\Stock", mappedBy="store") */ 
    protected $stockProducts; 
} 

庫存:

namespace Entity; 

use Doctrine\ORM\Mapping as ORM; 

/** @ORM\Table(name="stock") @ORM\Entity() */ 
class Stock 
{ 
    /** ORM\Column(type="integer") */ 
    protected $amount; 

    /** 
    * @ORM\Id() 
    * @ORM\ManyToOne(targetEntity="Entity\Store", inversedBy="stockProducts") 
    * @ORM\JoinColumn(name="store_id", referencedColumnName="id", nullable=false) 
    */ 
    protected $store; 

    /** 
    * @ORM\Id() 
    * @ORM\ManyToOne(targetEntity="Entity\Product", inversedBy="stockProducts") 
    * @ORM\JoinColumn(name="product_id", referencedColumnName="id", nullable=false) 
    */ 
    protected $product; 
} 
+0

好的,我將添加一些getter和setter,因爲使用此設置,我只會獲得主鍵並且運行沒有任何值:) – 2013-03-27 08:34:46

+0

當我使用此設置並嘗試使用Stock.store_id進行查詢時,出現錯誤「Stock has no field or association named store_id」。應該找到它,因爲該列存在於數據庫中。 – afilina 2013-08-06 13:23:02

+0

@afilina數據庫在生成模式時無關緊要--DBAL拋出異常,因爲它無法在DDL元數據(內存中)中找到列 – Ocramius 2013-08-08 08:41:19

16

學說處理多對多的關係就好了。

您遇到的問題是您不需要簡單的ManyToMany關聯,因爲關聯不能具有「額外」數據。

您的中間(股票)表,因爲它包含多於product_id和store_id,需要它自己的實體來模擬額外的數據。

所以,你真的想三類實體:

  • 產品
  • StockLevel
  • 商店

和兩個協會:

  • 產品一對多StockLevel
  • 商店一對多StockLevel
+1

謝謝你的回答!我添加了額外的字段到我的「股票」像表格。然而,當我運行'php app/console doctrine:mapping:import AppBundle yml'來從數據庫中導入模式時,原則仍然不考慮這個「連接表」並跳過它。我希望它能生成這個額外的映射yaml文件。有人有什麼主意嗎 ? ':('' – Stphane 2015-03-16 16:22:22

+0

答案不解決將數據寫入「連接」實體,這是一個問題,沒有聲明實體,可以請某人支持從表單傳遞數據的示例(CollectionType字段具有EntityType字段的嵌入表單) I無法將數據從嵌入式表單傳遞到主表單,並且正確保存字段集合 – zoore 2018-02-22 21:09:44