Assume the following AbstractPage
model:
假设以下抽象模型:
/*
* @ORM\Entity
* @ORM\Table(name="page")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="type", type="string")
* @ORM\DiscriminatorMap
* ({
* "page" = "Page",
* "link" = "Link"
* })
*/
And the following DQL query:
和以下DQL查询:
SELECT p FROM \Page\Model\AbstractPage
The generated SQL will be:
生成的SQL将是:
SELECT ... FROM page p0_ WHERE p0_.type IN ('page', 'link')
Now to the question: how can I remove the WHERE
clause from this query. On more complex queries this part of the WHERE
clause makes it not possible to use some indexes that are defined. This can be resolved by adding type
to the indexes, but this makes my indexes larger and I feel this is not necessary.
现在的问题是:如何从这个查询中删除WHERE子句。对于更复杂的查询,WHERE子句的这一部分不允许使用已定义的一些索引。可以通过向索引添加类型来解决这个问题,但是这会使索引变得更大,我认为这是不必要的。
The AbstractPage
is the root in the inheritance tree. Thus we are interested in ALL records in the table. Omiting the WHERE
part does precisely that.
AbstractPage是继承树中的根。因此,我们对表中的所有记录都感兴趣。省略WHERE部分就能做到这一点。
So the question is: how can I make Doctrine remove this WHERE
part where it is not necessary.
所以问题是:我怎样才能使教义在不需要的地方去除这部分。
Thanks!
谢谢!
1 个解决方案
#1
4
Here is the solution I can think out. The idea is to extend some doctrine classes to add functionality required. Keep models as they are now.
这是我能想到的解决办法。其思想是扩展一些doctrine类以添加所需的功能。保持现在的模型。
Create new class extending SqlWalker (update namespaces of course)
创建扩展SqlWalker的新类(当然是更新名称空间)
<?php
namespace Sad;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\SqlWalker;
class CustomSqlWalker extends SqlWalker
{
const IGNORE_DISCRIMINATION = 'ignoreDiscrimination';
/**
* {@inheritdoc}
*/
public function walkWhereClause($whereClause)
{
// Get list of aliases in which discrimination should be ignored
$ignoreDescription = $this->getQuery()->getHint(self::IGNORE_DISCRIMINATION);
if ($ignoreDescription !== false) {
// For each aliases...
foreach ($this->getQueryComponents() as $k => $component) {
// ...check if alias is in ignore list
if (in_array($k, $ignoreDescription)) {
/** @var $metaObj ClassMetadata */
$metaObj = $component['metadata'];
// Update inheritance type to disable discrimination where
if ($metaObj->isInheritanceTypeSingleTable()) {
$metaObj->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_NONE);
}
}
}
}
return parent::walkWhereClause($whereClause);
}
}
Then making query you do the following:
然后进行以下查询:
echo $entityManager->createQuery("SELECT p FROM \Sad\Schema\AbstractPage as p")->getSQL();
// Output: ELECT p0_.id AS id_0, p0_.name AS name_1, p0_.type AS type_2 FROM page p0_ WHERE p0_.type IN ('page', 'link')
$query = $entityManager->createQuery("SELECT p FROM \Sad\Schema\AbstractPage as p");
// Make sure query uses custom walker
$query->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Sad\CustomSqlWalker');
// Specify which aliases should ignore discrimination
$query->setHint(\Sad\CustomSqlWalker::IGNORE_DISCRIMINATION, array('p'));
echo $query->getSQL();
// Output: ELECT p0_.id AS id_0, p0_.name AS name_1, p0_.type AS type_2 FROM page p0_
#1
4
Here is the solution I can think out. The idea is to extend some doctrine classes to add functionality required. Keep models as they are now.
这是我能想到的解决办法。其思想是扩展一些doctrine类以添加所需的功能。保持现在的模型。
Create new class extending SqlWalker (update namespaces of course)
创建扩展SqlWalker的新类(当然是更新名称空间)
<?php
namespace Sad;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\SqlWalker;
class CustomSqlWalker extends SqlWalker
{
const IGNORE_DISCRIMINATION = 'ignoreDiscrimination';
/**
* {@inheritdoc}
*/
public function walkWhereClause($whereClause)
{
// Get list of aliases in which discrimination should be ignored
$ignoreDescription = $this->getQuery()->getHint(self::IGNORE_DISCRIMINATION);
if ($ignoreDescription !== false) {
// For each aliases...
foreach ($this->getQueryComponents() as $k => $component) {
// ...check if alias is in ignore list
if (in_array($k, $ignoreDescription)) {
/** @var $metaObj ClassMetadata */
$metaObj = $component['metadata'];
// Update inheritance type to disable discrimination where
if ($metaObj->isInheritanceTypeSingleTable()) {
$metaObj->setInheritanceType(ClassMetadata::INHERITANCE_TYPE_NONE);
}
}
}
}
return parent::walkWhereClause($whereClause);
}
}
Then making query you do the following:
然后进行以下查询:
echo $entityManager->createQuery("SELECT p FROM \Sad\Schema\AbstractPage as p")->getSQL();
// Output: ELECT p0_.id AS id_0, p0_.name AS name_1, p0_.type AS type_2 FROM page p0_ WHERE p0_.type IN ('page', 'link')
$query = $entityManager->createQuery("SELECT p FROM \Sad\Schema\AbstractPage as p");
// Make sure query uses custom walker
$query->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, 'Sad\CustomSqlWalker');
// Specify which aliases should ignore discrimination
$query->setHint(\Sad\CustomSqlWalker::IGNORE_DISCRIMINATION, array('p'));
echo $query->getSQL();
// Output: ELECT p0_.id AS id_0, p0_.name AS name_1, p0_.type AS type_2 FROM page p0_