单表继承(STI)与ManyToOne关系 [英] Single Table Inheritance (STI) with a ManyToOne relationship

查看:111
本文介绍了单表继承(STI)与ManyToOne关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对教义很新,所以任何一般的建议都是值得欢迎的。我正在尝试实现以下功能:

I'm pretty new to Doctrine, so any general advice is welcome. I'm trying to achieve the following:

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

A page can have both videos and photos. Both are media and share properties, so I thought Single Table Inheritance makes sense. Here are the relevant parts of my setup:

页面

/**
 * @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;
}

这个工作完全正常,但是这是我的问题 - 我如何抓取所有照片 s或视频 s的页面。我尝试添加如

This works perfectly fine, but -and this is my question- how do I fetch all Photos or Videos of a page. I've tried adding things like

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

页面,但这会导致模式错误,因为它没有在照片上定义的逆。任何帮助都非常感谢!

to Page, but this results in a schema error, since it doesn't have an inverse defined on Photo. Any help is greatly appreciated!

推荐答案

您可以将过滤器应用于媒体集

You can apply filter to the media collection

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

请记住,它将获取所有媒体单个选择查询,实例化照片和视频,然后过滤结果。这可能会影响性能,但您可能会受益于教条缓存,具体取决于您的方案。

Bear in mind, it will fetch all medias in a single select query, instantiate both Photos and Videos, and then filter the result. It may affect performance, but you may benefit from doctrine cache, depending on your scenario.

如果性能是关键,则可能需要在 PageRepository 实际上仅使用 dql dql的实例仅获取媒体子集,如查询类型

If performance is a key, you may need to implement a custom methods in PageRepository to actually fetch only subset of medias using instance of dql as described in Query the Type.

这篇关于单表继承(STI)与ManyToOne关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆