忽略了Doctrine生成的SQL的鉴别器部分 [英] Leave out discriminator part of Doctrine' generated SQL

查看:57
本文介绍了忽略了Doctrine生成的SQL的鉴别器部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假定以下 AbstractPage 模型:

/*
 *     @ORM\Entity
 *     @ORM\Table(name="page")
 *     @ORM\InheritanceType("SINGLE_TABLE")
 *     @ORM\DiscriminatorColumn(name="type", type="string")
 *     @ORM\DiscriminatorMap
 *     ({
 *         "page" = "Page",
 *         "link" = "Link"
 *     })
 */

DQL查询:

SELECT p FROM \Page\Model\AbstractPage

生成的SQL将是:

SELECT ... FROM page p0_ WHERE p0_.type IN ('page', 'link')

现在问题:如何从此查询中删除 WHERE 子句。在更复杂的查询中, WHERE 子句的这一部分使得无法使用某些已定义的索引。可以通过在索引中添加 type 来解决此问题,但这会使我的索引更大,并且我认为这是不必要的。

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.

AbstractPage 是继承树中的根。因此,我们对表中的所有记录都感兴趣。省略 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.

所以问题是:我如何使Doctrine删除此在哪里不需要的部分。

So the question is: how can I make Doctrine remove this WHERE part where it is not necessary.

谢谢!

推荐答案

这是我能想到的解决方案。想法是扩展一些学说类以添加所需的功能。
保持模型不变。

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.

创建扩展SqlWalker的新类(当然是更新名称空间)

Create new class extending SqlWalker (update namespaces of course)

<?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_

这篇关于忽略了Doctrine生成的SQL的鉴别器部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆