动态目标实体Doctrine 2和Symfony 2

5
我希望能够在一个实体上实现动态实体映射,并将其用于其他实体。例如,我有一个文件实体,它将存储MIME类型、映射键、名称等,还有一个包含它所属的实体ID的entity_id。映射键将确定类,因为这个文件实体将是多对多的。因此,文件实体的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;
}

Product 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;
}

But I have many other entities similar to Product and how do I make sure that when I call getFiles(), I get the files of the respective entity. I think it may work like this anyway, but is this the right way, or is there a better way?


为了获得更好的答案,请创建一个"最小、完整、可验证的示例",详情请参考Stack Overflow - tmthydvnprt
当然,我希望现在我已经编辑了正确的信息。 - deviprsd
2个回答

2

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

首先,重新评估:我经常发现,我实际上并不需要那么多不同的实体,它们可以合并成一个,从而简化一切。当我们没有必要(甚至不应该)时,我们经常过度设计和过度复杂化!

如果这不是一个选项:创建文件和所有其他(相关)实体之间的单独关系。是的,您的文件实体将充满关系。然后编写一个通用的访问getter,计算它连接到哪个实体并返回它(通过浏览所有连接或者通过从其他参数(例如您的mime类型)计算它,可以更加复杂且更快速)。

这样,您就可以隐藏所有这些关系的复杂性,使其与您的代码分离。

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

如果您找到了一种更优雅的、基于doctrine2的方法,请务必让我(和其他人)知道。


1
我刚刚更新了我的问题,并提供了一个可能的解决方案。我想到了这种方法,但我还没有尝试过它是否有效。 - deviprsd
我会尝试,但我不认为这会奏效,超类中不包含表格细节。 - deviprsd
如果您找到更优雅的方法来为这些单词设置“+”,请告诉我们!因为现在设置许多关系真的很痛苦,我的眼睛都要瞎了。我不明白为什么 ORM 没有像 ODM 中做的那样,为特定字段添加鉴别器类型,以描述如何解析多个实体...... 这种事情让我感到痛苦。我的情况是:我有一个翻译表用于所有实体,并且我无法将它们全部连接到一个表中。感谢 @Putr 给出的建议,我需要创建所有的关系。是否有任何关于我的情况的想法? - Nikita_kharkov_ua
1
@Nikita_kharkov_ua ORM 无法使用 discriminator 这样的字段,因为底层的 DBMS 需要有将表链接起来的外键。而 discriminator 更类似于多态关系,所以不允许这种链接。MongoDB 并没有外键的概念,并且在不久的将来也不太可能会有。至于我使用的解决方案,我有一个“标签”实体,可以从任何其他实体链接,但没有双向关联,即标签不知道它链接到了什么(您仍然可以使用 QueryBuilder 查询)。 - SteveB

1
我发现根据我的需求,我可以使用ManyToMany单向或OneToMany单向。但是对于双向,似乎没有解决方案。我有一些想法,但这只会使情况更加复杂。根据Doctrine的文档,生成的模式将是:
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);

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接