我正在尝试重现自动Doctrine机制来处理多对多的bidrectional关系,但引入了自定义连接表。
我已经深入研究了类似的问题:
我知道有一个额外字段的连接表是不再是一个关联,只是引用另外两个字段的第三个实体。从这个陈述中可以明显看出,人们不能指望它作为由Doctrine管理的隐含的多对多关联而开箱即用。
但我想让这个三重奏作为一个简单,直接,双向的多对多关联,这意味着使用代理方法并依赖逻辑类。
有一个类别实体和一个产品实体:
/**
* @ORM\Table(name="category")
* @ORM\Entity(repositoryClass="CategoryRepository")
*/
class Category
{
/**
...
*/
protected $id = null;
/**
* @ORM\OneToMany(targetEntity="CategoryProduct", mappedBy="category", fetch="LAZY", cascade={"persist"})
*/
protected $categoryProducts;
}
和
/**
* @ORM\Table(name="product")
* @ORM\Entity(repositoryClass="ProductRepository")
*/
class Product
{
/**
...
*/
protected $id = null;
/**
* @ORM\OneToMany(targetEntity="CategoryProduct", mappedBy="product", fetch="LAZY", cascade={"persist"})
*/
protected $categoryProducts;
}
当然还有加入实体:
/**
* @ORM\Table(name="category_product")
* @ORM\Entity(repositoryClass="CategoryProductRepository")
*/
class CategoryProduct
{
/**
...
*/
protected $id = null;
/**
* @ORM\ManyToOne(targetEntity="Category", fetch="EAGER", inversedBy="categoryProducts")
* @ORM\JoinColumn(onDelete="CASCADE")
*/
protected $category;
/**
* @ORM\ManyToOne(targetEntity="Product", fetch="EAGER", inversedBy="categoryProducts")
* @ORM\JoinColumn(onDelete="CASCADE")
*/
protected $product;
/**
* @ORM\Column(type="boolean", nullable=true)
*/
protected $starred = false;
}
如何以纯粹的ORM风格方式保留两个实体可用的最新CategoryProduct实体列表?在ORM中,所有内容都在Object层上进行管理。对DB的更改仅根据用户的请求进行,但只要从ORM的角度来看,它就不是强制性的。换句话说:
$category->addProduct($product);
不会向数据库写入任何内容,甚至不会将任何对象持久保存到实体管理器,但只要脚本运行,就可以从列表中检索或删除此产品。
对于自定义连接表,它是不同的,因为当想要添加产品时,他必须创建并持久化CategoryProduct实体。 那么如果我们需要从反面检索这种关联呢?。这是一个演示我的问题的代码示例:
$product->addCategory($category);
$category->addProduct($product);
在这种双向关联中,$category::addProduct
函数如何知道$product::addcategory
创建的CategoryProduct实体的实例?风险是为同一个关联创建两个类似的连接实体,我不知道如何避免它。