Symfony / Doctrine错误:" Class' FROM'没有定义。"在getResult()上

时间:2017-03-20 08:29:42

标签: symfony doctrine doctrine-query symfony-3.2

我正在开发我的第一个symfony应用程序,在尝试使用queryBuilder时,我已经在几个小时内遇到问题。

我尝试执行SQL查询,但收到以下错误:

  

request.CRITICAL:未捕获的PHP异常Doctrine \ ORM \ Query \ QueryException:" [语义错误]第0行,第288行附近' FROM StatsBundle \ Entity \ PlayerRealMatch':错误:Class& #39; FROM'未定义。"

基本上我存储了足球运动员的评分和目标,现在我想用总和和平均数来检索它的聚合。

我在服务中,并且我在我的PlayerRealMatchRepository中调用了一个方法,该方法的核心代码如下:

        $qb = $this->createQueryBuilder('prm');
        $qb->select(
            "SUM(prm.has_started) as tit,
            SUM(prm.has_entered) as rempl,
            SUM(prm.yellow_cards) as yc,
            SUM(prm.red_card) as rc,
            SUM(prm.goals) AS gf,
            SUM(prm.own_goals) as ga,
            AVG(prm.rating) as avg"
        )
            ->innerJoin('prm.realMatch', 'rm')
            ->where('prm.playerId = :idPlayer')
            ->groupBy('rm.season')
            ->setParameter('idPlayer', $player->getId())
            ->getQuery();
        $query =$qb->getQuery();
        $seasonData = $query->getResult();

如果我用调试器查看$ query对象的_dql属性,请查看我的内容:

SELECT SUM(prm.has_started) as tit,
                SUM(prm.has_entered) as rempl,
                SUM(prm.yellow_cards) as yc,
                SUM(prm.red_card) as rc,
                SUM(prm.goals) AS gf,
                SUM(prm.own_goals) as ga,
                AVG(prm.rating) as avg 
FROM StatsBundle\Entity\PlayerRealMatch prm 
INNER JOIN prm.realMatch rm 
WHERE prm.playerId = :idPlayer 
GROUP BY rm.season

对我来说看起来并不坏,你们对这里的错误有任何疑问吗?

注意:这是我试图实现的查询示例,它可以直接在我的数据库上完美运行:

SELECT SUM(prm.has_started) as tit,
                SUM(prm.has_entered) as rempl,
                SUM(prm.yellow_cards) as yc,
                SUM(prm.red_card) as rc,
                SUM(prm.goals) AS gf,
                SUM(prm.own_goals) as ga,
                AVG(prm.rating) as avg 
FROM player_real_match prm 
INNER JOIN real_match rm ON prm.real_match_id = rm.id 
WHERE prm.player_id = 327 
GROUP BY rm.season;

以下详细信息

3个实体:

  • 播放器
  • RealMatch:有关比赛的一般数据
  • PlayerRealMatch:比赛中球员的表现

以下是各自配置的摘录,以显示它们之间的关联方式。

StatsBundle\Entity\Player: 
...
    manyToOne:
        real_team:
            targetEntity: RealTeam
            inversedBy: players
            joinColumn:
                onDelete: CASCADE
                name: real_team_id
                referencedColumnName: id
    oneToMany:
        player_real_matches:
            targetEntity: PlayerRealMatch
            mappedBy: player 
...
StatsBundle\Entity\RealMatch:
...
    home_team:
        targetEntity: RealTeam
        inversedBy: home_matches
        joinColumn:
            onDelete: CASCADE
            name: home_team_id
            referencedColumnName: id
    away_team:
        targetEntity: RealTeam
        inversedBy: away_matches
        joinColumn:
            onDelete: CASCADE
            name: away_team_id
            referencedColumnName: id
oneToMany:
    player_real_matches:
        targetEntity: PlayerRealMatch
        mappedBy: real_match
...
StatsBundle\Entity\PlayerRealMatch:
...
manyToOne:
    real_match:
        targetEntity: RealMatch
        inversedBy: player_real_matches
        joinColumn:
            onDelete: CASCADE
            name: real_match_id
            referencedColumnName: id
    player:
        targetEntity: Player
        inversedBy: player_real_matches
        joinColumn:
            onDelete: CASCADE
            name: player_id
            referencedColumnName: id
...

从服务

调用存储库方法
    foreach ($players as $player) {
        $this->aggregatePlayerData($player, $match);
    }

    private function aggregatePlayerData(Player $player, RealMatch $match)
    {
        $playerStats = $this->_em
            ->getRepository('StatsBundle:PlayerRealMatch')
            ->getAggregatedStats($player, $match);
    }

public function __construct(EntityManager $entityManager)
{
    $this->_em = $entityManager;
}

这是关于我的服务的services.yml

stats.aggregator:
    class: StatsBundle\Service\Aggregator
    arguments: [ "@doctrine.orm.entity_manager"]

存储库方法

 /**
 * getAggregatedStats
 *
 * @param $player the player entity
 * @param RealMatch $match  the real match entity
 *
 * @return array
 */
public function getAggregatedStats($player, RealMatch $match)
{

    $qb = $this->createQueryBuilder('prm');
    $qb->select(
        "SUM(prm.has_started) as tit,
        SUM(prm.has_entered) as rempl,
        SUM(prm.yellow_cards) as yc,
        SUM(prm.red_card) as rc,
        SUM(prm.goals) AS gf,
        SUM(prm.own_goals) as ga,
        AVG(prm.rating) as avg"
    )
    ->from('StatsBundle:PlayerRealMatch', 'prm')
    ->innerJoin('prm.realMatch', 'rm')
    ->where('prm.playerId = :idPlayer')
    ->groupBy('rm.season')
    ->setParameter('idPlayer', $player->getId())
    ->getQuery();
    $query = $qb->getQuery();
    $seasonData = $query->getResult();

    return $seasonData;
}

对于这篇长篇文章感到抱歉,我试图尽可能清楚地记录它。 非常感谢你的帮助!

3 个答案:

答案 0 :(得分:4)

您正在尝试使用保留的sql字作为列名, 尝试改变

"AVG(prm.rating) as avg" -> "AVG(prm.rating) as avgRating"

答案 1 :(得分:0)

我终于找到了这个问题,我相信这是一个经典的初学者的错误:

在我的select指令中,我使用的是lower_case属性,因为这是我的SQL列格式化的方式。

然而,这不是我的实体属性的情况。所以这是我的选择指令的正确语法

   "SUM(prm.hasStarted) as tit,
    SUM(prm.hasEntered) as rempl,
    SUM(prm.yellowCards) as yc,
    SUM(prm.redCard) as rc,
    SUM(prm.goals) as gf,
    SUM(prm.ownGoals) as ga,
    AVG(prm.rating) as avg"

所以结论是:在执行DQL时,始终引用实体属性而不是数据库列。

错误信息虽然很奇怪,但我会喜欢更明确的内容,例如“实体X没有属性Y”

非常感谢Azam Alvi。

答案 2 :(得分:-1)

您在查询中没有从字段中提供尝试这样做

$qb = $this->createQueryBuilder('prm');
    $qb->select(
        "SUM(prm.has_started) as tit,
        SUM(prm.has_entered) as rempl,
        SUM(prm.yellow_cards) as yc,
        SUM(prm.red_card) as rc,
        SUM(prm.goals) AS gf,
        SUM(prm.own_goals) as ga,
        AVG(prm.rating) as avg"
    )
        ->from('StatsBundle:PlayerRealMatch ', 'prm') // this one is missing
        ->innerJoin('prm.realMatch', 'rm')
        ->where('prm.playerId = :idPlayer')
        ->groupBy('rm.season')
        ->setParameter('idPlayer', $player->getId());

    $seasonData = $qb->getQuery()->getResult();