symfony 如何在OneToMany/ManyToOne上订购

ao218c7q  于 2023-04-12  发布在  其他
关注(0)|答案(4)|浏览(99)

我有一个Product类,它有许多字段用于ManyToMany,例如成分,大小,物种等。总共大约14个不同的字段并不是所有的字段都与每个产品相关。
我把Map设置成这样

Class product {
/**
 * @var Species[]
 * @ORM\ManyToMany(targetEntity="Species")
 * @ORM\JoinTable(name="product_species",
 *      joinColumns={@ORM\JoinColumn(name="productId", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="speciesId", referencedColumnName="id")}
 *      )
 * @ORM\OrderBy({"name" = "asc"})
 */
private $species;

这对于多对多/多对一非常有效。
问题是在我的product_ingredients表中,我需要添加一个额外的字段,这意味着需要从ManyToMany切换到OneToMany/ManyToOne。

/**
     * @var ProductIngredient[]
     *
     * @ORM\OneToMany(targetEntity="ProductIngredient", mappedBy="product")
     * @ORM\JoinColumn(name="productId", referencedColumnName="id")
     */
    private $ingredients;

现在我的ProductIngredient实体看起来像这样

/**
     * @var IngredientType
     * @ORM\ManyToOne(targetEntity="IngredientType", fetch="EAGER")
     * @ORM\JoinColumn(name="ingredientTypeId", referencedColumnName="id")
     */
    private $ingredientType;

    /**
     * @var Ingredient
     *
     * @ORM\ManyToOne(targetEntity="Ingredient", inversedBy="products", fetch="EAGER")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="ingredientId", referencedColumnName="id")
     * })
     */
    private $ingredient;

    /**
     * @var Product
     *
     * @ORM\ManyToOne(targetEntity="Product", inversedBy="ingredients")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="productId", referencedColumnName="id")
     * })
     */
    private $product;

所以在我的产品类中,我使用了@ORM\OrderBy,这样物种就已经被订购了..有没有一种方法,我也可以在我的成分字段中这样做?
或者我的逻辑出错了,这些字段甚至不应该是产品类上的字段,而应该只是由存储库查找?
我想让它变得简单,这样我就可以像$product->getIngredients()一样循环遍历我的对象,而不是做

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

tzdcorbm1#

在Product实体中,还将orderBy添加到成分关系中

/**
 * ...
 * @ORM\OrderBy({"some_attribute" = "ASC", "another_attribute" = "DESC"})
 */
private $ingredients;

使用PHP 8属性:

#[ORM\OrderBy(['some_attribute' = 'ASC', 'another_attribute' = 'DESC'])]
private $ingredients;
ecfdbz9o

ecfdbz9o2#

好吧,我想出了一个黑客的方式…因为我真的只关心的排序输出,我做了一个基本的树枝扩展

use Doctrine\Common\Collections\Collection;

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;
}

我想避免这种黑客虽然仍然想知道一个真实的的解决方案

pcrecxhr

pcrecxhr3#

您应该在表单中使用'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”语句

pes8fvy9

pes8fvy94#

如果使用xmlMap,则可以使用

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

在你的<one-to-many>标签中。

相关问题