繁体   English   中英

Symfony2 / Doctrine在类表继承中间映射了超类

[英]Symfony2 / Doctrine mapped superclass in the middle of class table inheritance

我目前的模型结构如下:

/**
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="related_type", type="string")
 * @ORM\DiscriminatorMap({"type_one"="TypeOne", "type_two"="TypeTwo"})
 */
abstract class BaseEntity {

    ... (all the usual stuff, IDs, etc)

    /**
     * @ORM\OneToMany(targetEntity="Comment", mappedBy="baseEntity")
     */
    private $comments;
}

/**
 * @ORM\Entity
 */
class TypeOne extends BaseEntity {
    /**
     * @ORM\Column(type="string")
     */
    private $name;

    /**
     * @ORM\Column(type="string")
     */
    private $description;
}

/**
 * @ORM\Entity
 */
class TypeTwo extends BaseEntity {
    /**
     * @ORM\Column(type="string")
     */
    private $name;

    /**
     * @ORM\Column(type="string")
     */
    private $description;   
}

/**
 * @ORM\Entity
 */
class Comment {

    ... (all the usual stuff, IDs, etc)

    /**
     * @ORM\ManyToOne(targetEntity="BaseEntity", inversedBy="comments")
     */
    private $baseEntity;
}

这里的想法是能够将注释与任何其他表绑定。 到目前为止,这一切似乎都运行正常(授予,我仍然在探索设计选项,因此可以有更好的方法来实现这一点......),但我注意到的一件事是子类有一些共同的字段我想进入一个共同的父类。 我不想将它们移动到BaseEntity中,因为会有其他对象是BaseEntity的子对象,但是不会有这些字段。

我考虑在中间创建一个MappedSuperclass父类,如下所示:

/**
 * @ORM\MappedSuperclass
 */
abstract class Common extends BaseEntity {
    /**
     * @ORM\Column(type="string")
     */
    private $name;

    /**
     * @ORM\Column(type="string")
     */
    private $description;       
}

/**
 * @ORM\Entity
 */
class TypeOne extends Common {}

/**
 * @ORM\Entity
 */
class TypeTwo extends Common {}

我认为这可行,但是教条数据库模式生成器抱怨我不能在MappedSuperclass上有OneToMany映射。 我不认为这是一个问题,因为OneToMany映射仍然在根BaseEntity和Comment表之间。 是否有我应该使用的不同结构,或者其他方式使这些字段不同而不在BaseEntity上添加它们?

来自Docs:

映射的超类是一个抽象或具体的类,它为其子类提供持久的实体状态和映射信息, 但它本身不是一个实体 通常,这种映射的超类的目的是定义多个实体类共有的状态和映射信息。

也就是说,如何将一个实体与一个实体相关联?

更多来自文档:

映射的超类不能是实体, 它不是可查询的,并且由映射的超类定义的持久关系必须是单向的(仅具有拥有方)。 这意味着根本不可能在映射的超类上进行一对多关联。 此外,只有当映射的超类目前仅在一个实体中使用时,才能实现多对多关联。 为了进一步支持继承, 必须使用单个或连接表继承功能。

资料来源: http//docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html


更新

因为MappedSuperClass扩展了BaseEntity,所以它也继承了BaseEntity的关联,就像它自己的关联一样。 所以你有效地在MappedSuperClass上有一个OneToMany。

为了解决这个问题,你需要修改/扩展学说以按照你想要的方式工作。

就本机功能而言,您有两种选择:

类表继承您公共类和生成的数据库表示将具有公共字段,子类现在将只具有特定于自身的字段。 不幸的是,如果您只是为了对它们进行分组而尝试对公共字段进行分组,那么这可能是对您的数据的误传。

使公共实体看起来所有Mapped Super Class都是未在DB中表示的实体。 所以,改为使实体成为共同体。 缺点是你最终会得到一个数据库表,但你可以删除它。

我建议您再次查看数据,并确保只对字段进行分组(如果它们在名称和用途上都很常见)。 例如,ComputerBox,ShoeBox,Man和Woman都可能具有“height”属性,但在这种情况下,我不建议使用具有“height”属性的Common类,它们都继承自。 相反,我会有一个Box与ComputerBox和ShoeBox共有的字段,我会有一个人与男人和女人共同的字段。 在那种情况下,如果您愿意,Class Table Inheritance或单个表将完美地工作。

如果您的数据遵循该示例,请使用单表或类表继​​承。 如果没有,我可能会建议不要对字段进行分组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM