多层次不同类型的继承
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 ...
}
对于我的项目,我正在尝试使用 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
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 ...
}