【问题标题】:Symfony / Doctrine Error: "Class 'FROM' is not defined." on getResult()Symfony / Doctrine 错误:“未定义类 'FROM'。”在 getResult() 上
【发布时间】:2017-03-20 08:29:41
【问题描述】:

我正在开发我的第一个 symfony 应用程序,在尝试使用 queryBuilder 时,我已经为一个问题苦苦挣扎了几个小时。

我正在尝试执行 SQL 查询并收到以下错误:

request.CRITICAL:未捕获的 PHP 异常 Doctrine\ORM\Query\QueryException:“[语义错误] 第 0 行,'FROM StatsBundle\Entity\PlayerRealMatch' 附近的第 288 列:错误:未定义类 '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;
}

抱歉,这篇文章太长了,我试图尽可能清楚地记录下来。 非常感谢您的帮助!

【问题讨论】:

    标签: symfony doctrine doctrine-query symfony-3.2


    【解决方案1】:

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

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

    【讨论】:

    • 我遇到了同样的问题,只是我使用的是“count”。这救了我。
    【解决方案2】:

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

    在我的选择指令中,我使用了小写属性,因为这是我的 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 抽出宝贵时间。

    【讨论】:

      【解决方案3】:

      您没有在查询中给出 from 字段尝试这样做

      $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();
      

      【讨论】:

      • 谢谢你的建议,其实我已经试过了,没有成功,还是一样的错误。据我了解,这是通过以下方式隐式完成的: $this->createQueryBuilder('prm');因为我在 PlayerRealMatchRepository 上。它实际上显示在我的 _dql
      • 你能给我看一下这个查询的完整功能代码吗?还告诉我你是如何从 repo 调用这个函数的代码。
      • 我根据您的要求更新了原始帖子的描述
      • 你为什么要调用->getQuery()函数两次?删除第一个
      • 我这样做是出于调试目的,我想查询...刚刚更改为 $seasonData[$player->getId()] = $qb->getQuery()->得到结果();但当然它不会改变任何东西
      猜你喜欢
      • 1970-01-01
      • 2022-10-26
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多