多层次不同类型的继承

Multiple level of different kind of inheritance

对于我的项目,我正在尝试使用 Doctrine 的继承特性。我需要代表媒体(通过不同的 tables :一个 table 用于上传的文档,一个用于链接的视频,......等等)。

但是,视频可能因提供商而异(例如 Youtube、Dailymotion,随便你说)。因此,我正在考虑通过 SINGLE_TABLE 继承进行另一项继承,适合视频 table。

但是,当我声明我的实体时,似乎如果我在扩展 AbstractMedia 实体的 AbstractVideo 实体上添加 SINGLE_TABLE 继承注释,Video table 从未创建(也未检测到)。这是这两个实体的片段:

<?php
namespace Acme\Demo\Entity;

use Datetime;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="Media")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 */
abstract class AbstractMedia
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    // some other fields
}

/**
 * @ORM\Entity
 * @ORM\Table(name="Video")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="provider", type="string")
 * @ORM\DiscriminatorMap({})
 */
abstract class AbstractVideo extends AbstractMedia
{
    /** @ORM\Column(type="string") */
    private $name;

    // some other fields
}

我已经尝试将映射实体映射到 Foo 实体,扩展 AbstractVideo,但是当我尝试保留某些内容时,它说它不是有效实体。

有什么想法,或者我真的应该避免这么深的继承吗?谢谢

不太确定这是否正是您所需要的,但这是我使用的生产代码。

我们继承了这个文件,和其他实体一样,那些也被继承了。 重要的部分是将继承(扩展)实体添加到鉴别器映射。

/**
 * File
 *
 * @ORM\Table(name = "file")
 * @ORM\Entity(repositoryClass="Living\ApiBundle\Entity\File\FileRepository")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="type", type="string", length=64)
 * @ORM\DiscriminatorMap({
 *      "file"  = "Something\Entity\File\File",
 *      "image" = "Something\Entity\Image\Image",
 *      "specialImage" = "Something\Entity\Image\SpecialImage",
 * })
 */
class File implements FileEntityInterface

.....

/**
 * ImageFile
 *
 * @ORM\Table(name="image")
 * @ORM\Entity(repositoryClass="Living\ApiBundle\Entity\Image\ImageRepository")
 */
class Image extends File implements ImageEntityInterface

,Doctrine ORM不支持这个。所以为了做我想做的事,我将在对象的 data 属性 中存储一个值对象,存储 "child classes" 的 属性 而不是深度不同的类型继承。

<?php
class Video extends AbstractMedia
{
    // returns the value object youtube, dailymotion, ... etc
    public function getData();    
}

class Youtube
{
   //public function ...
}

class Dailymotion
{
   // public funciton ...
}