简体   繁体   English

带有额外字段的Doctrine 2和Many-to-many链接表

[英]Doctrine 2 and Many-to-many link table with an extra field

(Sorry for my incoherent question: I tried to answer some questions as I was writing this post, but here it is:) (对不起我的语无伦次问题:我在撰写这篇文章时试图回答一些问题,但这里是:)

I'm trying to create a database model with a many-to-many relationship inside a link table, but which also has a value per link, in this case a stock-keeping table. 我正在尝试在链接表中创建一个具有多对多关系的数据库模型,但每个链接也有一个值,在这种情况下是一个库存表。 (this is a basic example for more problems I'm having, but I thought I'd just test it with this before I would continue). (这是我遇到的更多问题的一个基本示例,但我认为在继续之前我只是用它来测试它)。

基本多商店,多产品存储系统的数据库模型

I've used exportmwb to generate the two Entities Store and Product for this simple example, both are displayed below. 我已经使用exportmwb为这个简单的例子生成了两个Entities Store和Product,两者都显示在下面。

However, the problem now is that I can't figure out how to access the stock.amount value (signed int, as it can be negative) using Doctrine. 但是,现在的问题是我无法弄清楚如何使用Doctrine访问stock.amount值(signed int,因为它可能是负数)。 Also, when I try to create the tables using doctrine's orm:schema-tool:create function 此外,当我尝试使用doctrine的orm创建表时:schema-tool:create function

从HeidiSQL看到的数据库布局

This yielded only two Entities and three tables, one as a link table without values and two data tables, as many-to-many relationships aren't entities themselves so I can only have Product and Store as an entity. 这只产生了两个实体和三个表,一个是没有值的链接表和两个数据表,因为多对多关系本身不是实体,因此我只能将Product和Store作为实体。

So, logically, I tried changing my database model to have stock as a separate table with relationships to store and product. 所以,从逻辑上讲,我尝试更改我的数据库模型,将库存作为一个单独的表,与商店和产品的关系。 I also rewrote the fieldnames just to be able to exclude that as a source of the problem: 我还重写了字段名,只是为了能够将其排除为问题的根源:

更改数据库布局

Then what I found was that I still didn't get a Stock entity... and the database itself didn't have an 'amount'-field. 然后我发现我仍然没有得到Stock实体......而且数据库本身没有'amount'字段。

I really needed to be able to bind these stores and products together in a stock table (among other things)... so just adding the stock on the product itself isn't an option. 我真的需要能够将这些商店和产品捆绑在一个库存表(以及其他东西)中......所以只是在产品本身上添加库存不是一种选择。

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

And when I create the database, it still doesn't give me the right fields in the stock table: 当我创建数据库时,它仍然没有在stock表中给我正确的字段:

从HeidiSQL看到的数据库布局

So, looking up some things here, I found out that many-to-many connections aren't entities and thus cannot have values. 所以,在这里查看一些内容,我发现多对多连接不是实体,因此不能有值。 So I tried changing it to a separate table with relationships to the others, but it still didn't work. 所以我尝试将它更改为一个与其他表有关系的单独表,但它仍然无效。

What am I doing wrong here? 我在这做错了什么?

A Many-To-Many association with additional values is not a Many-To-Many, but is indeed a new entity, since it now has an identifier (the two relations to the connected entities) and values. 与其他值的多对多关联不是多对多,但实际上是一个新实体,因为它现在具有标识符(与连接实体的两个关系)和值。

That's also the reason why Many-To-Many associations are so rare: you tend to store additional properties in them, such as sorting , amount , etc. 这也是多对多关联如此罕见的原因:您倾向于在其中存储其他属性,例如sortingamount等。

What you probably need is something like following (I made both relations bidirectional, consider making at least one of them uni-directional): 你可能需要的是跟随的东西(我将两个关系都设为双向,考虑使其中至少有一个是单向的):

Product: 产品:

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

Store: 商店:

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

Stock: 股票:

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

Doctrine handles many-to-many relationships just fine. Doctrine处理多对多关系就好了。

The problem that you're having is that you don't need a simple ManyToMany association, because associations can't have "extra" data. 您遇到的问题是您不需要简单的ManyToMany关联,因为关联不能有“额外”数据。

Your middle (stock) table, since it contains more than product_id and store_id, needs its own entity to model that extra data. 您的中间(库存)表,因为它包含的不仅仅是product_id和store_id,它需要自己的实体来建模额外的数据。

So you really want three classes of entity: 所以你真的想要三类实体:

  • Product 产品
  • StockLevel 库存水平
  • Store 商店

and two associations: 和两个协会:

  • Product oneToMany StockLevel 产品oneToMany StockLevel
  • Store oneToMany StockLevel 存储oneToMany StockLevel

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

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