Get elements from LazyLoadCollection

2019-07-12 04:26发布

问题:

I have found Doctrine\Common\Collections\Criteria to be a very useful concept, if they worked for me.

In a symfony controller, I am calling this code:

$criteria = Criteria::create()
    ->where(Criteria::expr()->gt('position', 0))
    ->orderBy(['riskPosition', Criteria::ASC]);
$positions= $this->getDoctrine()->getRepository(DataCategory::class)->matching($criteria);

dump($positions->count()); // dumps 1, correct!
dump($positions);
foreach($positions as $r)
    dump($r); // -> Unrecognized field: 0

dump($positions) gives

LazyCriteriaCollection {#881 ▼
  #entityPersister: JoinedSubclassPersister {#849 ▶}
  #criteria: Criteria {#848 ▼
    -expression: Comparison {#836 ▶}
    -orderings: array:2 [▶]
    -firstResult: null
    -maxResults: null
  }
  -count: 1
  #collection: null
  #initialized: false
}

As soon as I access an element of the returned array, I get an error

ORMException::unrecognizedField(0)
in vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php (line 1193)

But as soon as I want to access the elements (e.g. loop and dump) I get some error like An exception has been thrown during the rendering of a template ("Unrecognized field: 0").

As far as I have studied the code, the problem is that the query results have not been fetched from the database. Only count() works. How can I trigger this fetch?

Does it matter that my entity has @ORM\InheritanceType("JOINED")?

This code (circumventing the use of Criteria) does give correct results, but I'd like to use Criteria:

$riskPositions = $this->getDoctrine()->getRepository(DataCategory::class)
    ->createQueryBuilder('p')
    ->where('p.position > 0')
    ->orderBy('p.position', 'ASC')
    ->getQuery()
    ->execute();

回答1:

The issue is caused by line:

->orderBy(['riskPosition', Criteria::ASC]);

Doctrine\Common\Collections\Criteria `s orderBy accepts an array argument where

Keys are field and values are the order, being either ASC or DESC.

github link

Apparently, there is a mistake at doctrine s documentation.

So doctrine thinks that "0", which is the 1st key of the array argument, is the field to sort by, but cannot find it.

To solve, change the above line to:

->orderBy(['riskPosition' => Criteria::ASC]);