动态目标实体学说 2 和 Symfony 2


Dynamic Target entity Doctrine 2 and Symfony 2

我希望在一个实体上进行动态实体映射,该映射将被其他实体使用。例如,我有一个 File 实体,它将存储MIME类型、映射keyname等,还有一个entity_id,它将包含它所属实体的 id。映射key将确定类,因为此文件实体将是多对多的。因此,文件实体的targetEntity不是固定的。如何实现?

文件实体

<?php
namespace AppBundle'Entity;
use Doctrine'ORM'Mapping as ORM;
/**
 * File
 *
 * @ORM'Entity
 */
class File {
    //.... Other mapping properties
    /**
     * @ORM'ManyToOne(targetEntity="SuperClass", inversedBy="files")
     * @ORM'JoinColumn(name="entity_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $entity;
}

产品实体

namespace AppBundle'Entity;
use Doctrine'ORM'Mapping as ORM;
/**
 * Product
 *
 * @ORM'Entity
 */
class Product extends SuperClass {
    //.... Other mapping properties
    /**
     * @ORM'OneToMany(targetEntity="File", mappedBy="entity")
     */
    protected $files;
}

但是我还有许多其他类似于Product的实体,如何确保当我调用getFiles()时,我获得了相应实体的文件。我认为无论如何它都可以这样工作,但这是正确的方法,还是有更好的方法?

好的,这是我遇到的一个非常普遍的问题 - 如何将一个实体链接到许多其他非常相似的实体。

首先,重新评估:我经常发现,我实际上并不需要那么多不同的实体,并且可以通过简化所有内容将它们折叠成一个实体。当我们真的不需要(甚至不应该)时,我们经常过度设计和过度复杂化!

如果这不是一个选项:在文件和所有其他(相关)实体之间创建单独的关系。是的,您的文件实体将充满关系。然后编写一个通用的访问获取器,计算它连接到哪个实体并返回它(通过遍历所有连接,或者通过从其他参数(如 mime 类型)计算它,它可以比它更复杂 [并且更快] 从您的例子中计算它)。通过这种方式,您可以对代码的其余部分隐藏所有这些关系的复杂性。

如果您只需要一个足够好的解决方案,则此选项有效。更正确的方法是放弃两个字段中的学说关系和跟踪 ID 和相关实体类,并自己选择和实例化对象(在实体中,ofcorse)。但这更复杂,更容易出错。

如果你找到一种方法以更优雅、教义2支持的方式做到这一点,请告诉我(和我们其他人)知道。

我发现根据我的要求,我可以使用 ManyToMany 单向或 OneToMany Unidirectional。但对于双向,似乎没有解决方案。我有一些想法,但这只会使场景复杂化。根据学说文档,生成的架构将是

CREATE TABLE Product (
    id INT AUTO_INCREMENT NOT NULL,
    PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE Feature (
    id INT AUTO_INCREMENT NOT NULL,
    product_id INT DEFAULT NULL,
    PRIMARY KEY(id)
) ENGINE = InnoDB;
ALTER TABLE Feature ADD FOREIGN KEY (product_id) REFERENCES Product(id);

所以就像我在问题中建议扩展超类一样,如果超类本身是一个实体,有自己的表,包含一个将存储存储库路径的字段,并且以某种方式对其进行处理以返回正确的实体。