如何在OneToMany/ManyToOne上订购



我有一个产品类,上面有很多 ManyToMany的字段,例如成分、大小、物种等。总共约14个不同的领域并非所有字段都与每个产品相关。

我有这样的映射设置

Class product {
/**
 * @var Species[]
 * @ORMManyToMany(targetEntity="Species")
 * @ORMJoinTable(name="product_species",
 *      joinColumns={@ORMJoinColumn(name="productId", referencedColumnName="id")},
 *      inverseJoinColumns={@ORMJoinColumn(name="speciesId", referencedColumnName="id")}
 *      )
 * @ORMOrderBy({"name" = "asc"})
 */
private $species;

这适用于多对多/多对一。

问题出在我的product_ingredients表中,我需要添加一个额外的字段,这意味着需要从多对多切换到一对多/多对多所以像这样

/**
     * @var ProductIngredient[]
     *
     * @ORMOneToMany(targetEntity="ProductIngredient", mappedBy="product")
     * @ORMJoinColumn(name="productId", referencedColumnName="id")
     */
    private $ingredients;

现在我的产品成分实体看起来像这样

 /**
     * @var IngredientType
     * @ORMManyToOne(targetEntity="IngredientType", fetch="EAGER")
     * @ORMJoinColumn(name="ingredientTypeId", referencedColumnName="id")
     */
    private $ingredientType;

    /**
     * @var Ingredient
     *
     * @ORMManyToOne(targetEntity="Ingredient", inversedBy="products", fetch="EAGER")
     * @ORMJoinColumns({
     *   @ORMJoinColumn(name="ingredientId", referencedColumnName="id")
     * })
     */
    private $ingredient;
    /**
     * @var Product
     *
     * @ORMManyToOne(targetEntity="Product", inversedBy="ingredients")
     * @ORMJoinColumns({
     *   @ORMJoinColumn(name="productId", referencedColumnName="id")
     * })
     */
    private $product;

因此,在我的物种产品类中,我使用@ORM\OrderBy,以便物种已经订购。有没有办法让我也能为我的配料领域做到这一点?

还是我的逻辑做错了,这些甚至不应该是产品类上的字段,而应该只是由存储库查找?

我希望它很容易,这样我就可以像$product->getIngredients()一样遍历我的对象而不是做

$ingredients = $this->getDoctrine()->getRepository('ProductIngredient')->findByProduct($product->getId());

在产品实体中,您只需要将 orderBy 添加到成分关系中

/**
 * @ORMOrderBy({"some_attribute" => "ASC", "another_attribute" => "DESC"})
 */
private $ingredients;

使用 PHP 8 属性:

#[ORMOrderBy(['some_attribute' => 'ASC', 'another_attribute' => 'DESC'])]
private $ingredients;

好吧,我想出了一个黑客方法。由于我真的只关心输出的排序,所以我做了一个基本的树枝扩展

use DoctrineCommonCollectionsCollection;
public function sort(Collection $objects, $name, $property = null)
{
    $values = $objects->getValues();
    usort($values, function ($a, $b) use ($name, $property) {
        $name = 'get' . $name;
        if ($property) {
            $property = 'get' . $property;
            return strcasecmp($a->$name()->$property(), $b->$name()->$property());
        } else {
            return strcasecmp($a->$name(), $b->$name());
        }
    });
    return $values;
}

我想避免这个黑客,但仍然想知道一个真正的解决方案

您应该

在表单中使用"query_builder"选项:http://symfony.com/doc/master/reference/forms/types/entity.html#query-builder该选项的值可以是这样的:

function(EntityRepository $er) {
    return $er->createQueryBuilder('i')->orderBy('i.name');
}

不要忘记为 EntityRepository 添加"use"语句

如果使用 xml 映射,则可以使用

        <order-by>
            <order-by-field name="some_field" direction="ASC" />
        </order-by>

在您的<one-to-many>标签内。

相关内容

  • 没有找到相关文章

最新更新