错误:' c'在其声明范围之外使用

时间:2018-05-29 17:54:50

标签: php symfony doctrine-orm

应用程序有一个统计页面,代表几十个计算。为避免重复存储库中的代码错误

  

错误:' c'在声明范围之外使用

尝试将带条件的DQL插入QueryBuilder时发生

基本实体包括家庭和联系人。计算基于联系日期范围,站点(联系位置)和类型(联系类型)。有一个服务可以创建where子句和查询参数的数组,如下面的代码所示。

我知道如果所有代码都出现在一个函数中,计算就会起作用。似乎问题来自与Contact实体的连接及其必要的约束。在这种情况下可以完成DRY吗?

所有以下内容都出现在家庭实体的存储库中。

DQL是:

private function reportHousehold($criteria)
{
    return $this->createQueryBuilder('i')
        ->select('i.id')
            ->join('TruckeeProjectmanaBundle:Contact', 'c', 'WITH',
                'c.household = i')
            ->where($criteria['betweenWhereClause'])
            ->andWhere($criteria['siteWhereClause'])
            ->andWhere($criteria['contactWhereClause'])
            ->getDQL()
    ;
}

$条件示例:$criteria['betweenWhereClause'] = 'c.contactDate BETWEEN :startDate AND :endDate'

关于家庭的一项计算:

public function res($criteria)
{
    $parameters = array_merge(
        $criteria['betweenParameters'], $criteria['siteParameters'],
        $criteria['startParameters'], $criteria['startParameters'],
        $criteria['contactParameters']);
    $qb = $this->getEntityManager()->createQueryBuilder();

    return $this->getEntityManager()->createQueryBuilder()
            ->select('h.id, 12*(YEAR(:startDate) - h.arrivalyear) + (MONTH(:startDate) - h.arrivalmonth) Mos')
            ->from('TruckeeProjectmanaBundle:Household', 'h')
            ->distinct()
//DQL inserted here:
            ->where($qb->expr()->in('h.id', $this->reportHousehold($criteria)))
            ->andWhere($qb->expr()->isNotNull('h.arrivalyear'))
            ->andWhere($qb->expr()->isNotNull('h.arrivalmonth'))
            ->andWhere($criteria['startWhereClause'])
            ->setParameters($parameters)
            ->getQuery()->getResult()
    ;
}

2 个答案:

答案 0 :(得分:0)

您要么缺少getRepository()from()

试试这个(我的首选):

private function reportHousehold($criteria) {
    return $this->getEntityManager
                ->createQueryBuilder()
                ->select("i.id")
                ->from(YourEntity::class, "i")
                ->join("TruckeeProjectmanaBundle:Contact", "c", "WITH", "c.household=i.id")
                ->where($criteria['betweenWhereClause'])
                ->andWhere($criteria['siteWhereClause'])
                ->andWhere($criteria['contactWhereClause'])
                ->getQuery()
                ->execute();
}

或者这个

private function reportHousehold($criteria) {
    return $this->getEntityManager
                ->getRepository(YourEntity::class)
                ->createQueryBuilder("i")
                ->select("i.id")
                ->join("TruckeeProjectmanaBundle:Contact", "c", "WITH", "c.household=i.id")
                ->where($criteria['betweenWhereClause'])
                ->andWhere($criteria['siteWhereClause'])
                ->andWhere($criteria['contactWhereClause'])
                ->getQuery()
                ->execute();
}

小心,我假设你在Symfony 3或以上。
如果不是,请将YourEntity::class替换为Symfony 2语法"YourBundle:YourEntity"

答案 1 :(得分:0)

从某种意义上说,Preciel是正确的:解决方案确实需要使用$this->getEntityManager()->createQueryBuilder()。不是将DQL作为子查询注入,而是返回一个id数组并在IN子句中使用该数组。其结果是从计算中删除对住户实体以外的实体的任何考虑。结果如下:

public function res($criteria)
{
    $parameters = array_merge($criteria['startParameters'], $criteria['startParameters'], ['hArray' => $this->reportHousehold($criteria)]);
    $qb = $this->getEntityManager()->createQueryBuilder();

    return $this->getEntityManager()->createQueryBuilder()
            ->select('h.id, 12*(YEAR(:startDate) - h.arrivalyear) + (MONTH(:startDate) - h.arrivalmonth) Mos')
            ->from('TruckeeProjectmanaBundle:Household', 'h')
            ->distinct()
            ->where('h.id IN (:hArray)')
            ->andWhere($qb->expr()->isNotNull('h.arrivalyear'))
            ->andWhere($qb->expr()->isNotNull('h.arrivalmonth'))
            ->setParameters($parameters)
            ->getQuery()->getResult()
    ;
}

private function reportHousehold($criteria)
{
    $parameters = array_merge($criteria['betweenParameters'], $criteria['siteParameters'], $criteria['contactParameters']);
    return $this->createQueryBuilder('i')
            ->select('i.id')
            ->join('TruckeeProjectmanaBundle:Contact', 'c', 'WITH', 'c.household = i')
            ->where($criteria['betweenWhereClause'])
            ->andWhere($criteria['siteWhereClause'])
            ->andWhere($criteria['contactWhereClause'])
            ->setParameters($parameters)
            ->getQuery()->getResult()
    ;
}