Учитывая две доктрину сущностей (Person
и Company
), связанный один-ко-многим, и репозиторий, который выглядит примерно такSymfony2/Doctrine2 получить присоединился объектами из объекта QueryBuilder
namespace TestBundle\Entity\Repository;
use Doctrine\ORM\EntityRepository;
class PersonRepository extends EntityRepository {
public function findAllByAge($age) {
$qb = $this->createQueryBuilder('p')
->select('p','c')
->leftjoin('p.company', 'c')
->where("p.age = :age")
->setParameter('age', $age);
// ...
}
}
Как я мог извлекать сущность (объект или имя) Компании, предпочтительно из объекта $ qb (или из Alias, DQL, AST, parser и т. д.)?
В идеале, я хотел бы иметь массив, содержащий все псевдонимы, используемые экземпляром QueryBuilder, или по крайней мере те, которые определены в выберите метод, вместе с их субъектами, в виде:
[
'p' => 'TestBundle\Entity\Person',
'c' => 'TestBundle\Entity\Company',
// etc
]
В $qb->getDQLPart('join')
или даже что-то более низком уровне, как $qb->getQuery()->getAST()->fromClause->identificationVariableDeclarations
, есть информация о присоединениях к псевдонимам, но она содержит только корневую сущность и ее псевдоним (p = TestBundle \ Entity \ Person).
getRootEntity
, getRootAliases
, getAllAliases
не помогите, поскольку я получаю корневую сущность и/или все псевдонимы, но не могу связать их вместе.
$em->getClassMetadata($rootentity)->associationMappings
дает мне ассоциации для корневого объекта и содержит целевые сущности для объединений, но без псевдонимов. Я мог бы сопоставить имена полей с информацией от $qb->getDQLPart('join')
, но это привело бы меня в область, где мне пришлось бы обходить информацию рекурсивно от каждого объекта сущности. Похоже, это может вызвать серьезные ошибки.
Как Querybuilder преобразует ассоциации в правильные объекты? Или он вообще не делает этого, просто разбирается с материалами более низкого уровня, не зная, какие объекты он использует?
Мне нужна информация, поэтому я могу обеспечить, чтобы определенные поля объектов имели на них определенные вторичные индексы. Эти вторичные индексы могут быть установлены с помощью аннотаций и сохраняются в объекте по доктрине ($em->getClassMetadata($entity)->table['indexes']
).
Мне нужно знать (программно), какие поля имеют вторичные индексы при построении запроса, и предпочли бы оставаться как можно выше дерева абстракции.
Спасибо за ответ. Мне действительно нужно получить меньшее подмножество на уровне базы данных, поскольку оно включает таблицы с миллионами записей, часто со сложным соединением и упорядочением. Поэтому перед выполнением запроса мне нужно получить дополнительную информацию об индексах из доктрины. Мне нужна эта информация, чтобы иметь возможность применить andWhere() к querybuilder, после чего она дополнительно ограничена с помощью уставки doctrine. – Fx32
Ах, красивое редактирование. Вместе с несколькими часами чтения кода Doctrine на Github я пришел к выводу, что этот подход может не сработать или не без грубого злоупотребления Doctrine. Проблема в том, что у нас есть куча отдельных проектов Symfony с сотнями сущностей. Все они имеют один (частный) комплект поставщиков, который имеет методы, принимающие QB в качестве аргумента, применяя некоторые пользовательские функции (используя классы, которые расширяют «FunctionNode») и возвращают QB. Поэтому я не могу создать собственный запрос, просто возьмите конструктор запросов и верните построитель запросов. – Fx32
И хотя было бы неплохо обнаружить вторичные индексы, определенные в аннотации @Index сущности автоматически (для обеспечения безопасности), я думаю, мне просто нужно заставить конечных пользователей предоставить массив имен полей/псевдонимов, когда они называют преобразование/фильтр. – Fx32