Symonfy2,Doctrine:重复、默认或忽略 DiscriminatorMap?
Symonfy2, Doctrine: duplicate, default, or ignore DiscriminatorMap?
如何启用重复的鉴别器映射,允许 "default" 映射, 或 在 运行 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
.
我确实找到了这个 post:Leave out discriminator part of Doctrine' generated SQL
但是,它是 2014 年的版本,提到了版本差异,并且没有补偿 duplicate 或 default 映射.
编辑: 作为记录,我尝试了忽略路由——它没有用。
$q->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, MySqlWalker::class)
->setHint(MySqlWalker::IGNORE_DISCRIMINATION, array('ss'));
还是returns上面SQL的联合声明。它确实调用了 MySqlWalker;它确实进入 setInheritanceType()
调用,但它确实 not 忽略鉴别器映射。 :/
找到一个选项的答案:忽略
在 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);
}
}
}
}
仍然没有解决重复或默认鉴别器值...
如何启用重复的鉴别器映射,允许 "default" 映射, 或 在 运行 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
.
我确实找到了这个 post:Leave out discriminator part of Doctrine' generated SQL
但是,它是 2014 年的版本,提到了版本差异,并且没有补偿 duplicate 或 default 映射.
编辑: 作为记录,我尝试了忽略路由——它没有用。
$q->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, MySqlWalker::class)
->setHint(MySqlWalker::IGNORE_DISCRIMINATION, array('ss'));
还是returns上面SQL的联合声明。它确实调用了 MySqlWalker;它确实进入 setInheritanceType()
调用,但它确实 not 忽略鉴别器映射。 :/
找到一个选项的答案:忽略
在 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);
}
}
}
}
仍然没有解决重复或默认鉴别器值...