php - 具有多对一关系的单表继承 (STI)

标签 php doctrine-orm

我对 Doctrine 很陌生,所以欢迎任何一般性建议。我正在努力实现以下目标:

一个页面可以同时包含视频和照片。两者都是媒体和共享属性,所以我认为单表继承是有意义的。以下是我的设置的相关部分:

页面

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

    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="Media", mappedBy="page", cascade={"persist"})
     * @var ArrayCollection|Media[]
     */
    protected $media;

    /**
     * @return Media[]|ArrayCollection
     */
    public function getMedia()
    {
        return $this->media;
    }
}

媒体

/**
 * @ORM\Entity
 * @ORM\Table(name="media")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="media_type", type="string")
 * @ORM\DiscriminatorMap({"video" = "Video", "photo" = "Photo"})
 */
abstract class Media {

    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="string")
     */
    protected $url;

    /**
     * @ORM\ManyToOne(targetEntity="Page", inversedBy="media")
     */
    protected $page;
}

照片

/**
 * @ORM\Entity
 */
class Photo extends Media {

    /**
     * @ORM\Column(type="string")
     */
    protected $exif;
}

视频

/**
 * @ORM\Entity
 */
class Video extends Media {

    /**
     * @ORM\Column(type="integer")
     */
    protected $length;
}

这工作得很好,但是 - 这是我的问题 - 我如何获取页面的所有 PhotoVideo。我尝试添加类似

的内容
/**
 * @ORM\OneToMany(targetEntity="Photo", mappedBy="page", cascade={"persist"})
 * @var ArrayCollection|Photo[]
 */
protected $photos;

Page,但这会导致架构错误,因为它没有在 Photo 上定义逆向。非常感谢任何帮助!

最佳答案

您可以对媒体集合应用过滤器

class Page {
    .....
    public function getPhotos()
    {
        return $this->getMedia()->filter(
            function($media) {
                return $media instanceof Photo;
            }
        );
    }

    public function getVideos()
    {
        return $this->getMedia()->filter(
            function($media) {
                return $media instanceof Video;
            }
        );
    }
}

请记住,它将在单个 select 查询中获取所有媒体,实例化照片和视频,然后过滤结果。它可能会影响性能,但您可能会受益于原则缓存,具体取决于您的情况。

如果性能是关键,您可能需要在 PageRepository 中实现自定义方法,以使用 instance of dql 实际仅获取媒体子集,如 Query the Type 中所述.

关于php - 具有多对一关系的单表继承 (STI),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34458198/

相关文章:

php - 如何在 Linux 上从大文件中过滤掉数据?

javascript - 在 php 代码中使用 javascript 变量

php - preg_replace 在替换中使用匹配的模式

php - 带有模式注释的 Doctrine ORM 表

php - Symfony2 Doctrine2 - 根据学说 :mapping:import 从现有数据库生成多对多注释

php - Doctrine 2.4 PreUpdate获取原始数据返回新数据?

json - Symfony 2.6 - 流程图无法从 JSON 正确填充

php - 在每个函数调用 php 上执行一些东西

设置 'display' 属性的 Javascript 函数在某些情况下有效,而在其他情况下则无效

symfony - 如何使用 Doctrine ArrayCollection 的 forAll 方法?