我有一个带有连接条件的连接查询。它运行良好 getResult()
允许我访问查询结果。结果也很好(从phpmyadmin上看)。
$em = $this->getDoctrine()->getManager();
$allRows = $em->getRepository('CampaignBundle:Kpi')->createQueryBuilder('k')
->leftJoin('k.countryWeights', 'w', 'WITH', 'w.country = :country')
->setParameter('country', $country)
->addSelect('w')
->getQuery()->getResult();
连接的原因是我想检查另一个表(或实体)是否有相关的数据,如果它存在,我想在结果中包括它。这正是左连接所做的。
当我使用查询结果时,问题就出现了。例如:
foreach ($allRows as $row) {
$rowOut = array();
$rowOut['weight'] = ($row->getCountryWeights()) ? $row->getCountryWeights()[0]->getWeight() : 0;
}
相关实体属性的getter总是让我可以访问所有相关数据,就好像查询中没有连接条件一样。 $row->getCountryWeights()
始终为true,因为没有联接条件,联接不是空的。如何测试是否有数据被连接?如何访问连接的列,例如。 'weight'
? 在结果上尝试连接实体的getter似乎不起作用:
Attempted to call an undefined method named "getWeight"
其他信息:
/**
* Kpi
*
* @ORM\Table(name="kpi")
* @ORM\Entity
* @ORM\HasLifecycleCallbacks
*/
class Kpi
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* @ORM\OneToMany(targetEntity="CampaignBundle\Entity\KpiWeight", mappedBy="kpi", cascade={"ALL"})
*/
private $countryWeights;
}
/**
* KPIWeight
*
* @ORM\Table(name="kpi_weight")
* @ORM\Entity
*/
class KpiWeight
{
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Kpi", inversedBy="countryWeights")
* @ORM\JoinColumn(name="kpi", referencedColumnName="id", nullable=false)
*/
private $kpi;
/**
* @ORM\Id
* @ORM\ManyToOne(targetEntity="ZoneBundle\Entity\Country", inversedBy="countryObjectives")
* @ORM\JoinColumn(name="country", referencedColumnName="id", nullable=false)
*/
private $country;
/**
* @var float
* @ORM\Column(name="weight", type="float")
*/
private $weight;
}
这些实体清单不完整,但所有相关部分都应该在那里。
1条答案
按热度按时间wecizke31#
自
$row->getCountryWeights()
将返回一个Collection
对象,则需要测试集合。使用
Collection::first()
会回来的false
或者调用reset()
在集合的内部数组上。否则,可以使用
$row->getCountryWeights()->isEmpty()
.解释
例1:
假设您拥有以下数据集;
\活动包\实体\ kpi
\campaignbundle\entity\kpi::$countryweights
(OneToMany(targetEntity="CampaignBundle\Entity\CountryWeight"))
```| kpi_id | country | weight |
| 1 | A | 1 |
| 1 | B | 1 |
| 2 | A | 1 |
$allRows = $em->getRepository(\CampaignBundle\Entity\Kpi::class)->findAll();
$data = [];
foreach ($allRows as $row) {
foreach ($row->getCountryWeights() as $weight) {
$data[$row->getId()][$weight->getCountry()] = $weight->getWeight();
}
}
dump($data);
array:2 [▼
1 => array:2 [▼
"A" => 1
"B" => 1
]
2 => array:1 [▼
"A" => 1
]
]
$allRows = $em->getRepository(\CampaignBundle\Entity\Kpi::class)->createQueryBuilder('k')
->leftJoin('k.countryWeights', 'w', Join::WITH, $expr->eq('w.country', ':country'))
->setParameter('country', 'B')//<--- NOTE B is filtered
->addSelect('w')
->getQuery()
->getResult();
$data = [];
foreach ($allRows as $row) {
$firstWeight = $row->getCountryWeights()->first();
$data[$row->getId()][$firstWeight ? $firstWeight->getCountry() : null] = $firstWeight ? $firstWeight->getWeight() : 0;
}
dump($data);
array:2 [▼
1 => array:1 [▼
"B" => 1
]
2 => array:1 [▼
"" => 0
]
]
$em->clear(\CampaignBundle\Entity\Kpi::class);