Doctrine2 setFetchMode не работает с "EAGER"
Я также пытался получить связанные сущности "охотно", используя setFetchMode
в моем запросе, но следующее, похоже, не сработало:
$query->setFetchMode("MyProject\User", "address", "EAGER");
Когда я прыгнул в файлы , я обнаружил, что третий параметр $fetchMode
должен быть целым числом . Константы определены в Doctrine \ ORM \ Mapping: ClassMetadataInfo. При передаче строки по умолчанию будет Mapping\ClassMetadata::FETCH_LAZY
, потому что это условие if .
/**
* Specifies that an association is to be fetched when it is first accessed.
*/
const FETCH_LAZY = 2;
/**
* Specifies that an association is to be fetched when the owner of the
* association is fetched.
*/
const FETCH_EAGER = 3;
/**
* Specifies that an association is to be fetched lazy (on first access) and that
* commands such as Collection#count, Collection#slice are issued directly against
* the database if the collection is not yet initialized.
*/
const FETCH_EXTRA_LAZY = 4;
Таким образом, установка соответствующего целого числа решила проблему:
$query->setFetchMode("MyProject\User", "address", 3);
Или объявите класс use Doctrine\ORM\Mapping\ClassMetadata
сверху, а затем используйте константу:
$query->setFetchMode("MyProject\User", "address", ClassMetadata::FETCH_EAGER);
EDIT:
Поскольку здесь, похоже, много путаницы относительно правильного выбора ассоциаций, я отредактирую свой ответ и добавлю некоторую дополнительную информацию о том, как можно получить объединение с помощью своего репозитория.
Согласно документации Doctrine существует 2 типа соединений:
Обычные объединения : Используется для ограничения результатов и / или вычисления агрегированных значений.
Извлечение объединений : В дополнение к использованию регулярных объединений: используется для извлечения связанных объектов и включения их в гидратированный результат
запрос.
Таким образом, чтобы получить сущность, включающую в себя ее ассоциации, вам нужно будет «соединить» все эти ассоциации, чтобы убедиться, что они загружены с нетерпением.
Я обычно не использую DQL-запросы для получения сущностей и решения моих выборочных объединений, вместо этого я добавляю собственный метод в репозиторий, где я использую конструктор запросов. Это более гибко и намного более читабельно, чем использование DQL. Правильный DQL-запрос будет создан построителем запросов при вызове метода createQuery
. Вы можете проверить созданный DQL-запрос, конечно же, в целях отладки.
Пример такого пользовательского метода в репозитории сущностей Patientprofile
из приведенного выше вопроса:
public function findPatientByIdWithAssociations($id)(
// create a query builder for patient with alias 'p'
$qb = $this->createQueryBuilder('p')
->where('p.id = :patient_id')
->addSelect('pd')
->leftJoin('p.documentation', 'pd')
->addSelect('pa')
->leftJoin('p.address', 'pa')
->setParameter('patient_id', $id);
$query = $queryBuilder->getQuery();
return $query->getSingleResult();
}
И теперь вы можете использовать свой собственный метод репозитория, чтобы получить пациента по идентификатору (например, «555555557»), включая связи с документацией пациента и адресом:
$repository = $this->em->getRepository('Entities\Patientprofile');
$patient = $repository->findPatientByIdWithAssociations('555555557');
Убедитесь, что вы используете addSelect
и leftJoin
для быстрой загрузки.