Таблица ссылок Doctrine 2 и Many-to-many с дополнительным полем
(Извините за мой непоследовательный вопрос: я пытался ответить на некоторые вопросы, когда писал этот пост, но вот он:)
Я пытаюсь создать модель базы данных с отношением "многие ко многим" внутри таблицы ссылок, но также имеет значение для каждой ссылки, в данном случае таблицу запаса. (это основной пример для большего количества проблем, которые у меня возникают, но я думал, что просто проверю это, прежде чем продолжить).
![Database model for a basic multi-store, multi-product store-keeping system]()
Я использовал exportmwb для создания двух объектов Store and Product для этого простого примера, оба они отображаются ниже.
Однако теперь проблема заключается в том, что я не могу понять, как получить доступ к значению shareount (подписанное int, поскольку оно может быть отрицательным) с использованием Doctrine. Кроме того, когда я пытаюсь создать таблицы с помощью doctrine orm: schema-tool: create function
![the database layout as it is seen from HeidiSQL]()
Это дало только две сущности и три таблицы: одну как таблицу ссылок без значений и две таблицы данных, поскольку отношения "многие ко многим" не являются сущностями, поэтому я могу иметь только Продукт и Хранить как сущность.
Итак, логично, я попытался изменить модель базы данных, чтобы иметь запас как отдельную таблицу с отношениями для хранения и продукта. Я также переписал имена полей, чтобы иметь возможность исключить это как источник проблемы:
![changed database layout]()
Тогда я обнаружил, что я все еще не получил объект Stock... и сама база данных не имела поля "amount".
Мне действительно нужно было объединить эти магазины и продукты вместе в таблице акций (среди прочего)... так что просто добавление запаса на самом продукте не является вариантом.
[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]()
Итак, глядя на некоторые вещи здесь, я узнал, что соединения "многие ко многим" не являются сущностями и, следовательно, не могут иметь значений. Поэтому я попытался изменить его на отдельную таблицу с отношениями к другим, но она все еще не работает.
Что я здесь делаю неправильно?
Ответы
Ответ 1
Связь "многие-ко-многим" с дополнительными значениями не является "много-ко-многим", но действительно является новой сущностью, поскольку теперь она имеет идентификатор (два отношения к связанным объектам) и значения.
Это также причина, по которой ассоциации Many-to-Many настолько редки: вы склонны хранить в них дополнительные свойства, такие как sorting
, amount
и т.д.
То, что вам, вероятно, нужно, это следующее: я сделал оба отношения двунаправленными, считаю, что хотя бы одно из них однонаправлено):
Продукт:
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;
}
Наличие на складе:
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;
}
Ответ 2
Doctrine обрабатывает отношения "многие-ко-многим" просто.
Проблема, с которой вы сталкиваетесь, заключается в том, что вам не нужна простая ассоциация ManyToMany, потому что ассоциации не могут иметь "лишние" данные.
Ваша средняя (стоковая) таблица, так как она содержит больше, чем product_id и store_id, нуждается в ее собственной сущности для моделирования дополнительных данных.
Итак, вы действительно хотите три класса сущности:
- Продукт
- StockLevel
- Магазин
и две ассоциации:
- Продукт oneToMany StockLevel
- Сохранить однозначное StockLevel