Пользовательские функции DQL в doctrine2

Как использовать пользовательские функции DQL в partials для гидратации результата запроса.

Ищете способ использовать функции DQL в createQuery или любом другом доктрине (nativeSql, QueryBuilder), не обязательно использовать частичные, но он должен увлажнять мой массив на основе отношения таблиц, и он должен выбирать только выборочные поля

После выполнения запросов работает нормально:

$q = $em->createQuery("select " . "partial t.{id, description}, " . "partial ut.{id, firstName, lastName, email}, " . "DATE_FORMAT(ut.created, '%m-%d-Y') " . "from PMIUserBundle:Task t LEFT JOIN t.users ut"); 

DATE_FORMAT (ut.created, '% m-% d-Y') отлично работает, когда его из частичного.

DATE_FORMAT уже зарегистрирован как пользовательская функция в config.yml

config.yml:

 dql: datetime_functions: DATE_FORMAT: PMI\UserBundle\DoctrineFunctions\DateFormat 

Следующий запрос создает проблему:

  $q = $em->createQuery("select " . "partial t.{id, description}, " . "partial ut.{id, firstName, lastName, email, DATE_FORMAT(created, '%m-%d-Y')}, " . "DATE_FORMAT(ut.created, '%m-%d-Y') " . "from PMIUserBundle:Task t LEFT JOIN t.users ut"); 

дает ошибку:

 [Syntax Error] line 0, col 91: Error: Expected Doctrine\ORM\Query\Lexer::T_CLOSE_CURLY_BRACE, got '(' 

Ниже приведен мой класс DateFormat:

 class DateFormat extends \Doctrine\ORM\Query\AST\Functions\FunctionNode { protected $dateExpression; protected $formatChar; public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { return 'DATE_FORMAT('. $sqlWalker->walkArithmeticExpression($this->dateExpression) . ','. $sqlWalker->walkStringPrimary($this->formatChar). ')'; } public function parse(\Doctrine\ORM\Query\Parser $parser) { $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); $this->dateExpression = $parser->ArithmeticExpression(); $parser->match(Lexer::T_COMMA); $this->formatChar = $parser->StringPrimary(); $parser->match(Lexer::T_CLOSE_PARENTHESIS); } } 

РЕДАКТИРОВАТЬ:

Хорошо, поэтому Partial не позволит мне использовать функции DQL. Благодаря FuzzyTree для решения использовать ut->getFormattedCreatedDate() внутри моего класса сущности. Но мне все же интересно, что если мы группируем дочернюю таблицу и вычисляем некоторую сумму, используя функции mysql Aggregate.

Как достичь следующих критериев в doctrine2 с помощью createQuery, queryBuilder, nativeSQl или любым другим способом:

  1. Выбирать только выборочные поля
  2. Группировать по дочернему элементу таблицы с использованием функций агрегации
  3. Массив гидрата на основе табличных отношений, результаты совокупных функций должны быть в дочернем массиве.

каждый раз, если мы используем функции DQL, нужно ли создавать классы для таких, как я создал для DateFormat? что, если мы используем вложенные функции MySql, такие как

 GROUP_CONCAT(DISTINCT CONCAT(tags.id,',',tags.displayName) 

Спасибо, что прочитал мой вопрос.

Solutions Collecting From Web of "Пользовательские функции DQL в doctrine2"

Как использовать пользовательские функции DQL в partials для гидратации результата запроса.

partial ключевое слово указывает доктрине возвращать объекты, которые только частично гидратируются, и позволяет указать, какие поля вы хотите увлажнить.

При извлечении частичных сущностей вы ограничены выбором полей объекта (потому что в противном случае, где бы учение «хранилище» выбранного вами поля?), Поэтому невозможно указать функцию DQL как поле частичного объекта.

Как насчет этого?

  $qb = $this->_em->createQueryBuilder() ->select( 't.id, t.description, ' . 'ut.id, ut.firstName, ' . 'ut.lastName, ut.email, ' . 'DATE_FORMAT( ut.created, \'%m-%dY\' )' ) ->from( 'PMIUserBundle:Task', 't' ) ->leftjoin( 't.users', 'ut' ); $result = $qb->getQuery()->getResult(); 

Предполагая, что вы используете это в классе Repository (вот почему вызов $ this -> _ em).

Я заметил еще 2 вещи относительно пользовательской функции:

  1. Я лично определил его как «string_functions:» вместо этого в файле config.yml
  2. Я знаю, по крайней мере, один Bundle, который реализует эту настраиваемую функцию: https://github.com/beberlei/DoctrineExtensions

Надеюсь это поможет,

Tam

Не поддерживается

 PARTIAL ut.{id, firstName, lastName, email, DATE_FORMAT(created, '%m-%d-Y')} 

Использование DQL-функций внутри выделения частичных объектов, подобных этому, не поддерживается.

Это тоже не имеет особого смысла. В этом случае вы (вероятно) сопоставили поле, created как поле datetime , поэтому вы ожидаете полного значения DateTime . Но теперь вы просто используете часть даты. И все хуже: вы отформатировали значение таким образом, чтобы объект DateTime не мог быть создан (он ожидает Ymd H:i:s , а тип date ожидает Ymd ).

Для любого частичного выбора: вы не можете и не должны изменять значение поля.

альтернатива

Вместо того, чтобы увлажнять частичные объекты, вы можете просто использовать массивы. Используйте $q->getArrayResult() или $q->getScalarResult() , что лучше подходит для вашей цели.

Если хотите, вы можете группировать / вставлять результаты в метод репозитория. Пример:

 public function getSomeData() { $result = array(); $dql = <<<EOQ SELECT t.id AS t_id, t.description AS t_description, u.id AS u_id, u.firstName AS u_firstName, u.lastName AS u_lastName, u.email AS u_email, DATE_FORMAT(u.created, '%m-%d-Y') AS u_created FROM PMIUserBundle:Task t LEFT JOIN t.users u EOQ; $q = $this->getEntityManager()->createQuery($dql); foreach ($q->getScalarResult() as $row) { if (!isset($result[$row['t_id']])) { $result[$row['t_id']] = array( 'id' => $row['t_id'], 'description' => $row['t_description'], 'users' => array() ); $result[$row['t_id']]['users'][] = array( 'u.id' => $row['u_id'], 'u.firstName' => $row['u_firstName'], 'u.lastName' => $row['u_lastName'], 'u.email' => $row['u_email'], 'u.created' => $row['u_created'] ); } } return $result; } 

Вложенные функции DQL

Вложенные функции DQL не должны быть проблемой (если вы написали их правильно). И DISTINCT поддерживается из коробки.