Учение, тот же вызов, другой результат (и неправильный результат) - PullRequest
0 голосов
/ 04 октября 2019

Мой проект выглядит примерно так:

Сайты [] => 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();
...