一个应用程序有一页统计信息,表示数十个计算。为避免在存储库中重复代码,错误
错误:"c"在其声明范围之外使用
在尝试将带有条件的 DQL 插入查询生成器时发生。
基本实体包括家庭和接触。计算基于联系日期范围、站点(联系人位置(和类型(联系人类型(。有一个服务可以创建 where 子句和查询参数的数组,如下面的代码所示。
我知道如果所有代码都发生在一个函数中,计算就会起作用。问题似乎源于与联系人实体的连接及其必要的约束。在这种情况下可以完成 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示例:$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()
;
}
你要么缺少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"
从某种意义上说,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()
;
}