Doctrine2 - How can I order by a discriminator column?

后端 未结 3 1587
攒了一身酷
攒了一身酷 2021-02-13 04:36

How should I go about ordering by a discriminator column in a doctrine repository query?

I have a pretty straight forward setup, I have different types of payment detai

相关标签:
3条回答
  • 2021-02-13 05:02

    Can your try to use TYPE() or INSTANCE OF?

    related: https://groups.google.com/forum/#!topic/doctrine-user/JtCbwuN-37o

    However, this topic doesn't say if it is implemented or not. At the time it was written someone said order by wouldn't work.

    $dql = 'SELECT pd
            from
            AccountingBundle:PaymentDetail pd
            JOIN ClientProductBundle:ClientProduct cp
            WITH cp.payment_detail_id = pd.id
            WHERE
            cp.payment_detail_id = pd.id
            and cp.client_contact_id = :client_contact_id
            GROUP BY pd.id
            ORDER BY TYPE(pd)';
    
    0 讨论(0)
  • 2021-02-13 05:04

    Even though TYPE is not implemented yet into the core of doctrine it's still possible to implement it as a custom user function.

    Someone already did an amazing job and implemented it for us. Just in case the resource will be removed in the future, here is a slightly adjusted version for php7+:

    <?php
    use Doctrine\ORM\Mapping\ClassMetadataInfo;
    use Doctrine\ORM\Query\AST\Functions\FunctionNode;
    use Doctrine\ORM\Query\Lexer;
    use Doctrine\ORM\Query\Parser;
    use Doctrine\ORM\Query\QueryException;
    use Doctrine\ORM\Query\SqlWalker;
    
    class TypeFunction extends FunctionNode
    {
        /**
         * @var string
         */
        public $dqlAlias;
    
        public function getSql(SqlWalker $sqlWalker): string
        {
            /** @var ClassMetadataInfo $class */
            $class = $sqlWalker->getQueryComponent($this->dqlAlias)['metadata'];
            $tableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $this->dqlAlias);
    
            if (!isset($class->discriminatorColumn['name'])) {
                $message = 'TYPE() only supports entities with a discriminator column.';
                throw QueryException::semanticalError($message);
            }
    
            return $tableAlias . '.' . $class->discriminatorColumn['name'];
        }
    
        public function parse(Parser $parser)
        {
            $parser->match(Lexer::T_IDENTIFIER);
            $parser->match(Lexer::T_OPEN_PARENTHESIS);
            $this->dqlAlias = $parser->IdentificationVariable();
            $parser->match(Lexer::T_CLOSE_PARENTHESIS);
        }
    }
    

    Now you can order by the discriminator column by doing something like:

    SELECT e, TYPE(e) AS HIDDEN my_type FROM Entity e ORDER BY my_type DESC;
    
    0 讨论(0)
  • 2021-02-13 05:14

    It seems like the simplest solution (so far) is to add another field to the base class and copy the discriminator column value.

    The aforementioned TYPE(q) works only in WHERE clause.

    0 讨论(0)
提交回复
热议问题