在运行下面的 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');
我知道这是一个非常复杂的解决方案(可能仅适用于我的场景),所以我希望有人能给我另一种简单的方法来解决这个问题,非常感谢!
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 中选择鉴别器列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!