在教义2中使用部分对象语法+数组水合器为字段别名

Posted

技术标签:

【中文标题】在教义2中使用部分对象语法+数组水合器为字段别名【英文标题】:Aliasing fields using partial object syntax + array hydrator in doctrine 2 【发布时间】:2016-04-06 04:08:08 【问题描述】:

在 Doctrine 2 中使用 partial object syntax 时,有什么方法可以给字段起别名?

我知道我能做到:

$this->createQueryBuilder('user')->select([
     'user.id AS id',
     'user.firstName AS first_name',
     'user.lastName AS last_name',
     'user.email AS email',
     'user.dateCreated AS date_created'
])->getQuery()->getArrayResult();

但是我需要使用部分对象语法,以便学说在嵌套的关系层次结构中检索结果:

$this->createQueryBuilder('team')
    ->select('PARTIAL team.id, name, dateCreated, s, PARTIAL e.id, name')
    ->innerJoin('team.session', 's')
    ->innerJoin('s.event', 'e')
    ->getQuery()->getArrayResult();

我在 Doctrine\ORM\Internal\Hydration\ArrayHydrator 中进行了挖掘,但没有看到任何钩子或任何东西,而且看起来 Doctrine 没有 postSelect 事件或允许我实现自己的突变的东西。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

效率不高,但我最终选择了subclassing the ArrayHydrator 并自己修改了密钥。

希望有更好的方法,如果没有,我希望这对某人有所帮助

【讨论】:

【参考方案2】:

问题不仅在于别名,还在于括号。基本上,Partial object syntax 很差,不允许使用别名或括号。它需要一个昏迷或列表的结尾,其他一切都会抛出一个语法错误。

我想使用这样的 SUM() 函数检索部分对象集合

public function findByCompetition(array $competition)

    $competitionField = $competition['field'] ?? 'Id';
    $competitionValue = $competition['value'] ?? 0;

    $teamsCompStatsByComp = $this->createQueryBuilder('t')
        ->select('partial t.Id, competitionId, competitionOldId, teamId, teamOldId, SUM(goalsAttempted) goalsAttempted')
        ->where('t.'.$competitionField.' = ?1')
        ->groupBy('t.teamId')
        ->orderBy('t.Id', 'ASC')
        ->setParameter('1', $competitionValue)
        ->getQuery()
        ->getResult()
    ;

    return new ArrayCollection($teamsCompStatsByComp);

但遇到同样的错误

[语法错误] line 0, col 85: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_CURLY_BRACE, got '('

我必须以数组的形式检索数据,在外键上使用 IDENTITY(),然后手动水合我的实体

public function findByCompetition(array $competition)

    $competitionField = $competition['field'] ?? 'Id';
    $competitionValue = $competition['value'] ?? 0;

    $teamsCompStatsByComp = $this->createQueryBuilder('t')
        ->select('t.Id, IDENTITY(t.competitionId) competitionId, t.competitionOldId, IDENTITY(t.teamId) teamId, t.teamOldId, SUM(goalsAttempted) goalsAttempted')
        ->where('t.'.$competitionField.' = ?1')
        ->groupBy('t.teamId')
        ->orderBy('t.Id', 'ASC')
        ->setParameter('1', $competitionValue)
        ->getQuery()
        ->getResult()
    ;

    foreach ($teamsCompStatsByComp as $key => $teamCompStats) 
        $teamsCompStatsByComp[$key] = new TeamStatistics($teamCompStats);
    

    return new ArrayCollection($teamsCompStatsByComp);

我认为我们应该在 Github 上打开一个问题以改进部分语法行为。

【讨论】:

以上是关于在教义2中使用部分对象语法+数组水合器为字段别名的主要内容,如果未能解决你的问题,请参考以下文章

使用 Doctrine2 从数组水合到对象

教义queryBuilder:返回对象而不是数组

水合没有查询的中继片段

教义:将模型值设置为数组

使用自定义 Doctrine 2 数据类型的依赖注入

链接器为rodata 部分计算错误的地址