首页 > 解决方案 > 按字段对学说的@OneToMany ArrayCollection 进行排序

问题描述

关闭问题是在此处输入链接描述,但我需要更深入的排序:

/**
 * @var ArrayCollection[SubjectTag]
 *
 * @ORM\OneToMany(targetEntity="SubjectTag", mappedBy="subject")
 * @ORM\OrderBy({"position" = "ASC"})
 * @Assert\Valid()
 */
protected $subjectTags;

在 subjectTag 我有:

/**
 * @var ArrayCollection[tag]
 *
 * @ORM\OneToMany(targetEntity="Tag", mappedBy="subject")
 * @ORM\OrderBy({"name" = "ASC"})
 * @Assert\Valid()
 */
protected $tags;

现在我想按 SubjectTag.tags 排序。我怎样才能做到这一点?

编辑:

Entity1.php: /** * @ORM\ManyToOne(targetEntity="Entity2", referencedColumnName="id", nullable=false) * @Assert\Valid() */ protected $entity2;

Entity2.php: /** * @ORM\ManyToOne(targetEntity="Entity3", referencedColumnName="id", nullable=false) * @Assert\Valid() */ protected $entity3;

Entity3.php:

/**
 * @ORM\Column(type="integer", nullable=true)
 */
protected $position;

现在.. 我想在 Entity1 Entity2 中按位置排序。默认情况下我该怎么做?

标签: symfonyentity

解决方案


正如我之前的评论中所解释的,您应该在与您的基本实体相对应的存储库类中进行自定义查询(您没有给出它的名称)。

所以在你的 App\Repository\"YourBaseENTityName"Repository 类中,你做这样的事情。

public function findOrderByTags()
{
    return $this
        ->createQueryBuilder('baseEntityAlias')
        ->addSelect('st')
        ->addSelect('t')
        ->leftJoin('baseEntityAlias.subjectTags', 'st')
        ->leftJoin('st.tags', 't')
        ->orderBy('st.position', 'ASC')
        ->addOrderBy('t.name', 'ASC')
        ->getQuery()
        ->getResult();
}

此外,根据您的问题,我不确定您要执行什么样的订单。这里 baseEntity->subjectTags 将按其位置排序,然后 baseEntity->subjectTags->tags 将按名称排序。

现在您可以从基础实体存储库类中调用此方法

希望对您有所帮助。


编辑:这是一种为您的 queryBuilder 引入默认行为并重用它的方法。

/**
 * In your EntityRepository add a method to init your query builder
 */
public function createDefaultQueryBuilder(string $alias = 'a')
{
    return $this
        ->createQueryBuilder($alias)
        ->addSelect('st')
        ->addSelect('t')
        ->leftJoin('baseEntityAlias.subjectTags', 'st')
        ->leftJoin('st.tags', 't')
        ->orderBy('st.position', 'ASC')
        ->addOrderBy('t.name', 'ASC');
}

/**
 * In this example, I override the default find method. I don't recommend it thought
 */
public function find($id, $lockMode = null, $lockVersion = null)
{
    return $this
        ->createDefaultQueryBuilder()
        ->where('a.id = :id')
        ->setParameter('id', $id)
        ->getQuery()
        ->getOneOrNullResult();
}

如您所见,我重用了 createDefaultQueryBuilder 方法,以便在关系中使用 subjectTags 和标签 init 获得默认行为,并以正确的方式排序。


推荐阅读