我想用重复选项创建ManyToMany关系。一个USER可以拥有多个CARS,并且许多CARS可以属于各种USER。同时,一个USER可以拥有许多相同类型的汽车。
我如何在Symfony 4和Doctrine中解决这个问题?
据推测,你有两个实体,如User
和Car
所描述的,并定义了它们之间的ManyToMany
关系。它可能看起来像这样:
User.php
class User
{
// ...
/**
* @ManyToMany(targetEntity="App\Entity\Car", inversedBy="users")
*/
private $cars;
// ...
}
Car.php
class Car
{
// ...
/**
* @ManyToMany(targetEntity="App\Entity\User", mappedBy="cars")
*/
// ...
private $users;
}
Doctrine会自动在它们之间创建一个中间表,类似users_cars
有两列:user_id
和car_id
。他们将分别持有users
和cars
的外键。你的问题是Doctrine创建了这两列的复合主键,这意味着它必须是唯一的,你不能有这样的东西:
user_id | car_id
------------------
1 | 1
1 | 1
这应该是例如:
Konrad | Porsche 911
Konrad | Porsche 911
换句话说,康拉德有两辆同型号的车。
您可以将ManyToMany
关系分解为两个ManyToOne
并为中间表定义您自己的实体:
Ownership.php
class Ownership
{
// ...
/**
* @ManyToOne(targetEntity="App\Entity\User", inversedBy="cars_owned")
*/
private $user;
/**
* @ManyToOne(targetEntity="App\Entity\Car", inversedBy="owners")
*/
private $car;
// ...
}
在OneToMany
和User
建立适当的Car
关系。现在你可以在你的表ownerships
中有重复项。这使您可以灵活地添加有关所有权的更多信息,可能是用户购买汽车时的购买日期。
我想强调命名是编程中最重要的事情之一。用一些预见的方法命名你的类和方法。他们描述了什么,他们做了什么?
对我而言,用户如何拥有同一辆车的次数并不是很明显。我正在考虑汽车一词的实体车辆。也许你应该宁愿称之为实体CarModel
或CarBrand
。 User
也不是很直观,我宁愿选择Owner
或Person
,但这取决于你的应用程序的进一步业务逻辑。