How to select discriminator column in doctrine 2(如何在学说 2 中选择鉴别器列)
问题描述
在运行下面的 DQL 时仅从原则 2 中选择鉴别器列时我需要一些帮助
I need some help when select only discriminator column from doctrine 2 when run the DQL below
SELECT p.type FROM AppBundleEntityProduct p
type
是实体 AppBundleEntityProduct
@ORMDiscriminatorColumn(name="type", type="smallint")`
@ORMDiscriminatorMap({
"0" = "AppBundleEntityProduct",
"1" = "AppBundleEntityProductSingleIssue",
"2" = "AppBundleEntityProductCountBasedIssue",
"3" = "AppBundleEntityProductTimeBasedIssue"
})
我知道 type
不是实体中的真正属性,但无论如何我可以这样做吗?
I know that type
is not a real property in entity, but is there anyway for me to do that?
提前致谢!
在阅读了 2 天的 Doctrine 代码后,我决定覆盖 SqlWalker 并通过下面的代码片段创建新的 Hydrator
After 2 days for reading Doctrine codes, I decided to override SqlWalker and create new Hydrator by the snippets below
<?php
namespace ...;
use DoctrineORMQuerySqlWalker;
class CustomSqlWalker extends SqlWalker
{
const FORCE_GET_DISCRIMINATOR_COLUMN = 'forceGetDiscriminatorColumn';
const DISCRIMINATOR_CLASS_MAP = 'discriminatorClassMap';
/**
* {@inheritdoc}
*/
public function walkSelectClause($selectClause)
{
$sql = parent::walkSelectClause($selectClause);
$forceGetDiscriminatorColumn = $this->getQuery()->getHint(self::FORCE_GET_DISCRIMINATOR_COLUMN);
if (empty($forceGetDiscriminatorColumn)) {
return $sql;
}
foreach ($this->getQueryComponents() as $key => $queryComponent) {
if (!in_array($key, $forceGetDiscriminatorColumn)) {
continue;
}
$metadata = $queryComponent['metadata'];
$discriminatorColumn = $metadata->discriminatorColumn['name'];
$tableName = $metadata->table['name'];
$tableAlias = $this->getSQLTableAlias($tableName, $key);
$discriminatorColumnAlias = $this->getSQLColumnAlias($discriminatorColumn);
$sql .= ", $tableAlias.$discriminatorColumn AS $discriminatorColumnAlias";
}
return $sql;
}
}
定制保湿器
<?php
namespace ...;
use DoctrineORMInternalHydrationArrayHydrator;
use PDO;
class CustomHydrator extends ArrayHydrator
{
/**
* {@inheritdoc}
*/
protected function hydrateAllData()
{
$result = array();
$rootClassName = null;
if (isset($this->_hints['forceGetDiscriminatorColumn']) &&
isset($this->_hints['discriminatorClassMap'])) {
$rootClassName = $this->_hints['discriminatorClassMap'];
}
while ($data = $this->_stmt->fetch(PDO::FETCH_ASSOC)) {
foreach ($data as $key => $value) {
if ($this->hydrateColumnInfo($key) != null ||
empty($rootClassName)) {
continue;
}
$metadata = $this->getClassMetadata($rootClassName);
$discriminatorColumn = $metadata->discriminatorColumn;
$fieldName = $discriminatorColumn['fieldName'];
$type = $discriminatorColumn['type'];
$this->_rsm->addScalarResult(
$key, $fieldName, $type
);
}
$this->hydrateRowData($data, $result);
}
return $result;
}
}
配置自定义水化器
orm:
...
hydrators:
CustomHydrator: YourNamespaceToCustomHydrator
最后一步
$query = $queryBuilder->getQuery();
$query->setHint(DoctrineORMQuery::HINT_CUSTOM_OUTPUT_WALKER, 'YourNamespaceToCustomSqlWalker');
$query->setHint(YourNamespaceToCustomSqlWalker::FORCE_GET_DISCRIMINATOR_COLUMN, array($rootAlias)); // this alias will be used in CustomSqlWalker class
$query->setHint(YourNamespaceToCustomSqlWalker::DISCRIMINATOR_CLASS_MAP, $this->getClassName()); // this full-qualify class name will be used in CustomHydrator class
$products = $query->getResult('CustomHydrator');
TL;DR
我知道这是一个非常复杂的解决方案(可能仅适用于我的场景),所以我希望有人能给我另一种简单的方法来解决这个问题,非常感谢!
TL;DR
I know this is a very complicated solution (may be just for my scenario), so I hope someone could give me another simple way to fix that, thanks so much!
推荐答案
没有直接访问鉴别器列.
There is no direct access to the discriminator column.
可能会发生特殊类型的实体应该被查询的情况.因为没有直接访问鉴别器列,Doctrine 提供了 INSTANCE OF 结构.
It may happen that the entities of a special type should be queried. Because there is no direct access to the discriminator column, Doctrine provides the INSTANCE OF construct.
您可以使用 INSTANCE OF
DQL 如文档中所述.例如:
You can query for the type of your entity using the INSTANCE OF
DQL as described in the docs. As example:
$query = $em->createQuery("SELECT product FROM AppBundleEntityAbstractProduct product WHERE product INSTANCE OF AppBundleEntityProduct");
$products = $query->getResult();
希望能帮到你
这篇关于如何在学说 2 中选择鉴别器列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何在学说 2 中选择鉴别器列


基础教程推荐
- 在 yii2 中迁移时出现异常“找不到驱动程序" 2022-01-01
- phpmyadmin 错误“#1062 - 密钥 1 的重复条目‘1’" 2022-01-01
- 如何在 Symfony 和 Doctrine 中实现多对多和一对多? 2022-01-01
- HTTP 与 FTP 上传 2021-01-01
- PHP 守护进程/worker 环境 2022-01-01
- 在 CakePHP 2.0 中使用 Html Helper 时未定义的变量 2021-01-01
- 使用 PDO 转义列名 2021-01-01
- Doctrine 2 - 在多对多关系中记录更改 2022-01-01
- 找不到类“AppHttpControllersDB",我也无法使用新模型 2022-01-01
- 如何在 XAMPP 上启用 mysqli? 2021-01-01