3

该声明

我正在尝试重现用于处理多对多双向关系的自动 Doctrine 机制,但引入了自定义连接表。

我已经深入研究过类似的问题:

我知道带有额外字段的连接表不再是关联,只是引用另外两个实体的第三个实体。从该声明中,很明显,人们不能期望它作为由 Doctrine 管理的隐式多对多关联开箱即用。

但我想让这三重奏作为一个简单、直接、双向的多对多关联工作,这意味着使用代理方法并依赖逻辑类。

编码

有一个 Category 实体和一个 Product 实体:

/**
 * @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 中,一切都在对象层上进行管理。仅根据用户的请求对 DB 进行更改,但只要仅从 ORM 的角度工作,就不是强制性的。换句话说:

$category->addProduct($product);

不会向数据库写入任何内容,甚至不会将任何对象持久化到实体管理器,但只要脚本运行,仍然可以从列表中检索或删除该产品。

在自定义连接表的情况下,情况有所不同,因为当想要添加产品时,他必须创建并持久化 CategoryProduct 实体。那么如果我们需要从反面检索这个关联呢?. 这是一个演示我的问题的代码示例:

$product->addCategory($category);
$category->addProduct($product);

在这种双向关联中,$category::addProduct函数如何知道由创建的 CategoryProduct 实体的实例$product::addcategory?风险是为同一个关联创建两个相似的连接实体,我不知道如何避免它。

4

0 回答 0