Разделение проблем - ИМХО правильный аргумент, на который стоит взглянуть. Есть несколько подходов к go for, которые во многом зависят от того, как вы получаете объект. Однако, на мой взгляд, задача сущности НЕ состоит в том, чтобы получить данные других сущностей из базы данных, это забота репозитория или , возможно, контроллера. Итак, давайте посмотрим, как это сделать ...
Один из способов - автоматически получить родительский объект / объекты. В зависимости от вашего варианта использования вы можете сделать это в целом (через fetch="EAGER"
- см .: @ ManyToOne / @ OneToOne ), в противном случае вы могли бы реализовать специальную функцию репозитория, которая выбирает дополнительные сущности. Если у ваших сущностей всегда есть не более одного родительского элемента, это может полностью сократить количество запросов с 3 до 1, поскольку родительский и родительский элементы родительских сущностей могут быть извлечены одновременно.
// in BazRepository
public function getWithParents($id) {
$qb = $this->createQueryBuilder('baz');
$qb->leftJoin('baz.bar', 'bar')
->addSelect('bar')
->leftJoin('bar.foo', 'foo')
->addSelect('foo')
->where('baz.id = :id')
->setParameter('id', $id);
return $qb->getQuery()->getOneOrNullResult();
}
если дочерний объект обращается к родительскому объекту, он должен просто использовать объект из кеша и избегать второго запроса (источник: https://symfonycasts.com/screencast/doctrine-relations/join-n-plus-one)
Если сущностей уже «слишком много», вы может немного обмануть, (снова) создав собственный метод репозитория, который не только извлекает сущность Baz, но также и значение Foo.fooProperty и устанавливает его для виртуального / временного свойства в сущности Baz.
// in BazRepository
public function getWithFooProperty(int $id) {
$qb = $this->createQueryBuilder('baz');
$qb->leftJoin('baz.bar', 'bar')
->lefTJoin('bar.foo', 'foo')
->select('foo.fooProperty as fooProperty')
->where('baz.id = :id')
->setParameter('id', $id);
$result = $qb->getQuery()->getResult(); // should be an array with an array with two keys, but I might be wrong
if(count($result) == 0) {
return null;
}
$baz = $row[0][0];
$baz->fooProperty = $row[0][1];
return $baz;
}
(Отказ от ответственности: проверьте результат $ здесь, чтобы убедиться, что доступ правильный)
теперь вы можете получить доступ к нему в Baz :
function getFooProperty() {
if(isset($this->fooProperty)) {
return $this->fooProperty;
} else {
// fallback, in case entity was fetched by another repository method
return $this->getBar()->getFoo()->getFooProperty();
}
}