如何从存储库中获取鉴别器类型

时间:2018-03-01 23:01:09

标签: php doctrine symfony-2.8

我目前正在使用一个表继承来为我的一个实体在教义中。标题看起来像这样:

/**
 * Flux
 *
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="type", type="string")
 * @ORM\DiscriminatorMap({"flux" = "Flux", "news" = "FluxNews", "mission" = "FluxMission", "offer" = "FluxOffer", "survey" = "FluxSurvey", "linkedin" = "FluxLinkedin", "facebook" = "FluxFacebook", "youtube" = "FluxYoutube", "twitter" = "FluxTwitter"})
 * @ORM\Entity(repositoryClass="AppBundle\Repository\FluxRepository")
 */
class Flux
{

    protected $type = "flux";

    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /* other fields */

}

我正在尝试在flux存储库中创建一个函数,它将从所有flux对象获取数据。我想收集的一个重要数据是对象的类型(鉴别器字段),以了解它是什么类型的对象。

在我的存储库中,我的选择看起来像:

$queryBuilder->select('f.id', 'f.type', 'f.createdAt', 'IDENTITY(f.createdBy) as CreatedBy','COUNT(DISTINCT c.id) as allClicks', 'COUNT(DISTINCT IDENTITY(c.clicker)) as clicks', 'f.postUrl')
            ->groupBy('f.id');

fflux。如果我删除'f.type'它可以正常工作,但我需要这些数据。 如果我保留'f.type',我会收到以下错误:

  

[语义错误]第0行,第15行附近'type,f.createdAt,':错误:类AppBundle \ Entity \ Flux \ Flux没有名称类型的字段或关联

我想这是因为type是鉴别器字段,它不在正常字段中。我有办法在存储库中访问该数据吗?

我可以在我的控制器中访问,但我真的想保持我的代码干净,并在存储库中对这些数据进行所有查询。 到目前为止,我看到的唯一选择是创建另一个juste保存相同类型但仍然不干净的字段,我想知道是否有一种方法可以使用doctrine来获取该字段的值。

2 个答案:

答案 0 :(得分:1)

根据docs,您可以使用 INSTANCE OF 来执行此操作。

如果您想使用鉴别器值,使用类元数据并构建 CASE 表达式,您可以为每个实例选择值:

$meta = $em->getMetadataFactory()->getMetadataFor(Flux::class);
$discriminatorMap = $meta->discriminatorMap;
$caseQl = '(case';
foreach ($discriminatorMap as $fieldValue => $class) {
    $caseQl .= " when p INSTANCE OF " . $class . " then '" . $fieldValue . "'";
}
$caseQl .= ' else 0 end) as HIDDEN atype';
$qb->addSelect($caseQl);
$qb->having("atype LIKE :type");
$qb->setParameter('type', '%FluxNew%');

请注意,字段atype定义为 HIDDEN ,因此不会在结果中返回。

此解决方案 需要使用,而不是在哪里(因为atype是计算值)。

参考文献:

答案 1 :(得分:0)

请参阅this question。但我认为这种方式实在太复杂了。

如果我是你,我会覆盖您的查询。像这样:

$queryBuilder->select(f, COUNT(DISTINCT c.id) as allClicks, COUNT(DISTINCT IDENTITY(c.clicker)) as clicks)->from(Flux f)->groupBy(f.id);

您将获得混合结果,请参阅docs

因此,从f获取所需类型。

我希望你明白了。