代码之家  ›  专栏  ›  技术社区  ›  Liora Haydont

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

  •  3
  • Liora Haydont  · 技术社区  · 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');
    

    f 成为 flux . 如果我删除 'f.type' 它工作正常,但我需要这些数据。 如果我保留 'f.type' ,我得到以下错误:

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

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

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

    2 回复  |  直到 8 年前
        1
  •  2
  •   Jannes Botis    6 年前

    根据 docs ,您可以使用 的实例 去做吧。

    要使用鉴别器值,请使用 类元数据 以及构建 案例 表达式,可以为每个实例选择值:

    $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字段定义为 隐藏的 ,这样就不会在结果中返回它。

    也适用于此解决方案 需要使用,而不是在何处使用(因为atype是一个计算值)。

    或者,您可以使用 条令\ORM\Query::HINT\u INCLUDE\u META\u列 要在结果中包含外键列值,请执行以下操作:

    $paginator->getQuery()
    ->setHint(\Doctrine\ORM\Query::HINT_INCLUDE_META_COLUMNS, true)
    ->setHydrationMode(\Doctrine\ORM\Query::HYDRATE_ARRAY);
    

    参考文献:

        2
  •  0
  •   Denis Alimov    8 年前

    请参见 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 .

    我希望你明白了。