【问题标题】:Symonfy2, Doctrine: duplicate, default, or ignore DiscriminatorMap?Symonfy2,Doctrine:重复、默认或忽略 DiscriminatorMap?
【发布时间】:2018-05-11 18:50:49
【问题描述】:

如何启用重复的鉴别器映射,允许“默认”映射,在运行 DQL 查询时完全忽略鉴别器映射?

设置:

// DQL Query:
$this->createQueryBuilder('s')
     ->select(['s.serverId', 'p.projectName'])
     ->leftJoin('s.serverServices', 'ss')
     ->leftJoin('ss.serverServiceProjects', 'ps')
     ->leftJoin('ps.project', 'p')
     ->getQuery()
     ->getArrayResult()

// Mapping
/**
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="service_type_id", type="integer")
 * @ORM\DiscriminatorMap({
 *     "1" = "AppBundle\Entity\ServerService",
 *     "2" = "AppBundle\Entity\ServerService",
 *       [...]
 *     "12" = "AppBundle\Entity\Service\SubService",
 *     "" = "AppBundle\Entity\ServerService"
 * })
 */

生成的join部分:

   LEFT JOIN server_services s2_ ON s0_.server_id = s2_.server_id AND s2_.service_type_id IN ('1', '12') 

这是完全错误的。我有一个 1 - 12 的完整映射。还有一个 "" 空字符串匹配。如果一行没有已知映射(在我的代码中)或者它为空,则应将其设置为默认基 ServerService

我确实找到了这个帖子:Leave out discriminator part of Doctrine' generated SQL

但是,它是在 2014 年,提到了版本的差异,并且不补偿 duplicatedefault 映射。

编辑:为了记录,我尝试了忽略路线——它没有用。

   $q->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, MySqlWalker::class)
        ->setHint(MySqlWalker::IGNORE_DISCRIMINATION, array('ss'));

仍然返回上面的 SQL 联合语句。它确实调用了 MySqlWalker;它确实进入了setInheritanceType() 调用,但它确实忽略了鉴别器映射。 :/

【问题讨论】:

    标签: php symfony doctrine-orm dql symfony-2.8


    【解决方案1】:

    找到一个选项的答案:忽略

    在 Doctrine 2.2.x 中,我的语句在 JOIN 中,而不是在 WHERE 子句中。使用Leave out discriminator part of Doctrine' generated SQL 中的示例,我必须重载->walkJoin() 方法才能让忽略正常工作:

    /**
     * {@inheritdoc}
     */
    public function walkJoin($join)
    {
        $this->checkForHint();
        return parent::walkJoin($join);
    }
    
    protected function checkForHint()
    {
        $ignoreDescription = $this->getQuery()->getHint(self::IGNORE_DISCRIMINATION);
    
        if ($ignoreDescription) {
            foreach ($this->getQueryComponents() as $k => $component) {
                if (in_array($k, $ignoreDescription)) {
                    /** @var $meta ClassMetadata */
                    $meta = $component['metadata'];
                    $meta->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_NONE);
                }
            }
        }
    }
    

    仍然没有解决重复默认鉴别器值...

    【讨论】:

    • 您是否尝试过完全不声明DiscriminatorMap?默认处理应涵盖您的所有用例。包括在处理 *ToOne 和 *ToMany 以及扩展类时。example
    • 只有名称匹配类才有效。使用数字鉴别器时,Doctrine 无法自动破译正确的类。
    • 嗯,我不记得我评论和回答了哪些问题,但那是在过去 2 个月内。我查看了 Doctrine 对 Discriminator 声明的处理,我注意到他们只在字符串表示中使用了它 [discriminator]。因此,数字不完全(如果有的话)支持。至少,我认为这是我当时正在研究的歧视者。不过现在该睡觉了,所以如果你起床了,请随时查看我与 Doctrine 相关的活动,应该是在过去 2 个月内。
    • 快看,found it 虽然没有真正解释,对不起。更多信息可能在我的this old answer
    猜你喜欢
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多