我希望在一个实体上进行动态实体映射,该映射将被其他实体使用。例如,我有一个 File 实体,它将存储MIME
类型、映射key
、name
等,还有一个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);
所以就像我在问题中建议扩展超类一样,如果超类本身是一个实体,有自己的表,包含一个将存储存储库路径的字段,并且以某种方式对其进行处理以返回正确的实体。