How do I order by a property that isn't a DB column using Doctrine?

前提是你 提交于 2019-12-24 05:57:17

问题


When defining a relationship, there is a property on the related model (not a DB column), but I would like to sort by it (in the @OrderBy annotation).

I have a base model that is extended using single table inheritance. The property in question is basically an order property that is specified in each child class, but is not saved to the DB.

(I don't want to add an order column to the DB table, since the ordering depends purely on which child class the discriminator is mapped to. There is already a unique constraint so that each child class can be used no more than once in the relationship.)

Here's a really simplified version of my code...

Base entity:

/**
 * @ORM\Entity
 * @ORM\Table(name="base")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="class_name", type="string")
 *
 * @ORM\DiscriminatorMap({
 *   "Base" = "Models\Base",
 *   "ChildA" = "Models\ChildB",
 *   "ChildB" = "Models\ChildA"
 * })
 **/
class Base 
{
    /** @ORM\Column(type="string") **/
    protected $class_name;

    /**
     * @ORM\ManyToOne(targetEntity="Related", inversedBy="collection")
     **/
    protected $related;

    // this is just a plain ol' property (not in the DB)
    protected $order;

    public function getClassName()
    {
        return $this->class_name;
    }
}

Children:

/**
 * @ORM\Entity
 * @ORM\Table(name="child_a")
 **/
class ChildA extends Base
{
    $order = 1;
}

/**
 * @ORM\Entity
 * @ORM\Table(name="child_b")
 **/
class ChildB extends Base
{
    $order = 2;
}

Related entity:

/**
 * @ORM\Entity
 * @ORM\Table(name="related")
 **/
class Related
{
    /**
     * @ORM\OneToMany(targetEntity="Base", mappedBy="related")
     * @ORM\OrderBy({"order"="ASC"})
     **/
    protected $collection;

    public function getCollection()
    {
        $em = App::make('Doctrine\ORM\EntityManagerInterface');

        // map each Base instance to the appropriate child class
        return $this->collection->map(function ($base) use ($em) {
            $class_name = $base->getClassName();
            return $em->find($class_name, $base->getId());
        });
    }
}

Is it possible to use the order property for ordering the collection relationship? (Ordering based on class_name using a switch-like construct would also be valid, but I haven't found any way to do that either, and it would be harder to maintain.)

Thanks in advance!


回答1:


The directive beginning with ORM is very much telling Doctrine you're doing referencing a property that has a relationship with a table field. You can't use ORM directives on fields that don't exist. Doctrine annotations: OrderBy

You would have to implement this in a function, best in the model itself (within your getCollection() function), or if you're using a framework like Symfony place it in a function of the repository class for this entity. You'd have to use PHP sorting functions to do this. SQL/DQL won't work either because the property isn't related to a field in the table.



来源:https://stackoverflow.com/questions/32701272/how-do-i-order-by-a-property-that-isnt-a-db-column-using-doctrine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!