Мой проект выглядит примерно так:
Сайты [] => ComputedValue [] => ComputedValueData []
(у меня 13 сайтов, около 100 ComputedValue для сайта и более 30kComputedValueData by ComputedValue)
Я делаю команду для выполнения некоторого кода для всех ComputedValue, или если я поставлю аргумент только один ...
$sites = $sitesRepository->findAll();
foreach ($sites as $sites) {
foreach ($site->getComputed() as $computed) {
$this->computeComputed($computed);
}
}
или
$computedValue = $computedValueRepository->find(intval($computedId));
$this->computeComputed($computedValue);
В начале computeComputed()
я хочу получить самое старое (юноши?! Зависит от вашей точки зрения) значение ...
Так что в ComputedValueDataRepository я делаю эту функцию:
public function getDate(DataSourceInterface $dataSource, $orderBy)
{
$qbId = $this->getQueryBuilder();
$exp = $orderBy === 'ASC'
? $qbId->expr()->min($this->getPropertyName('date'))
: $qbId->expr()->max($this->getPropertyName('date'))
;
$qbId
->select($this->getPropertyName('id'))
->addSelect($exp . ' AS dateMax')
->andWhere($qbId->expr()->eq($this->getPropertyNameDataSourceFromDataSourceValue($dataSource), ':dataSource'))
->setParameter('dataSource', $dataSource)
;
$resultId = $qbId->getQuery()->getSingleResult();
$qbObj = $this->getQueryBuilder();
$qbObj
->andWhere($qbObj->expr()->eq($this->getPropertyName('date'), ':date'))
->andWhere($qbObj->expr()->eq($this->getPropertyNameDataSourceFromDataSourceValue($dataSource), ':dataSource'))
->setParameter('dataSource', $dataSource)
->setParameter('date', $resultId['dateMax'])
;
$resultObj = $qbObj->getQuery()->getSingleResult();
if ($resultObj instanceof ComputedWValue) {
dump($dataSource->getId());
$iddebug = $resultObj->getComputedW()->getId();
dump([
'idComputedW' => $iddebug,
'$resultObj' => $resultObj->setComputedW(new ComputedW()), // remove computedW for debug dump
]);
dump($this->getFullSQL($qbId->getQuery()));
dump($this->getFullSQL($qbObj->getQuery()));
}
return $resultObj == null ? null : $resultObj->getDate() ;
}
getPropertyNameDataSourceFromDataSourceValue () является хаком для устаревшей концепции неправильного обращения
protected function getPropertyNameDataSourceFromDataSourceValue(DataSourceInterface $dataSource)
{
if ($dataSource instanceof ComputedW) {
return $this->getPropertyName('computedW');
}
if ($dataSource instanceof ComputedCost) {
return $this->getPropertyName('computedCost');
}
// ... some other if like this
throw new \RuntimeException('dataSource type from dataSourceValue unknown');
}
И для отладки я использую этот код https://stackoverflow.com/a/27621942/1318115
В обоих случаях getFullSQL()
return
"SELECT d0_.id AS id_0, MAX(d0_.date) AS sclr_1 FROM data d0_ WHERE (d0_.data_id = 179) AND d0_.kind IN ('ComputedWValue')"
"SELECT d0_.id AS id_0, d0_.date AS date_1, d0_.value AS value_2, d0_.flag AS flag_3, d0_.kind AS kind_4, d0_.data_id AS data_id_5 FROM data d0_ WHERE (d0_.date = "2019-10-02 17:50:00" AND d0_.data_id = 179) AND d0_.kind IN ('ComputedWValue')"
Так что доктрина выполняет точно такой же запрос ...
В случае только с одним computedValue
у меня есть такой результат:
179
array:2 [
"idComputedW" => 179
"$resultObj" => xxxxxx\ApiBundle\Entity\ComputedWValue {#1546
#computedW: xxxxxx\ApiBundle\Entity\ComputedW {#1553
/// ... emptyObj , remove for debug clear
}
#id: 41716009
#date: DateTime {#1520
+"date": "2019-10-02 17:50:00.000000"
+"timezone_type": 3
+"timezone": "Europe/Berlin"
}
#value: 2771907.373
#flag: null
}
]
Но в контексте цикла
179
array:2 [
"idComputedW" => null
"$resultObj" => xxxxxx\ApiBundle\Entity\ComputedWValue {#3408
#computedW: xxxxxx\ApiBundle\Entity\ComputedW {#3635
/// ... emptyObj , remove for debug clear
}
#id: 41716009
#date: DateTime {#3444
+"date": "2019-10-02 18:00:00.000000"
+"timezone_type": 3
+"timezone": "Europe/Berlin"
}
#value: 2771907.373
#flag: null
}
]
Первый:
dump($dataSource->getId());
$iddebug = $resultObj->getComputedW()->getId();
технически самДело в том, что в контексте цикла getComputedW () -> getId () возвращает ноль?
И моя главная проблема ... ПОЧЕМУ моя дата не очень хорошая? (в bdd запись имеет значение «2019-10-02 17:50:00» для значения даты)
Кажется, что возвращение доктрины и кэшированное значение: /
РЕДАКТИРОВАТЬ:
я действительно заменяю свое возвращение этим, и это кажется работающим (но, кажется, уродливым: /)
$resultObj = $qbObj->getQuery()->getSingleResult();
if ($resultObj === null) {
return null;
}
$this->getEntityManager()->detach($resultObj);
$trustObj = $this->find($resultObj->getId());
return $trustObj->getDate();