35

我有一个 Product 类,其中包含许多字段用于 ManyToMany,例如成分、大小、物种等。总共大约 14 个不同的字段并非所有字段都与每个产品相关。

我有这样的映射设置

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());
4

4 回答 4

80

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

/**
 * ...
 * @ORM\OrderBy({"some_attribute" = "ASC", "another_attribute" = "DESC"})
 */
private $ingredients;
于 2012-09-19T13:45:46.357 回答
6

好吧,我想出了一个 hackish 方式。因为我真的只关心输出的排序,所以我做了一个基本的 twig 扩展

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

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

于 2012-09-20T02:27:01.440 回答
4

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

于 2013-04-20T09:21:01.370 回答
1

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

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

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

于 2018-04-17T12:20:51.973 回答