如何在OneToMany / ManyToOne上订购

时间:2012-09-18 14:01:17

标签: symfony doctrine-orm

我有一个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());

5 个答案:

答案 0 :(得分:70)

在Product实体中也只是将orderBy添加到成分关系

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

答案 1 :(得分:6)

我想出了一个hackish方式..因为我真的只关心输出的排序,我做了一个基本的枝条扩展

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

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

答案 2 :(得分: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添加“use”语句

答案 3 :(得分:0)

正如我在类似问题中的指示,你应该编写一个连接查询,以便ORM命令工作,请参阅此处以供参考。 http://www.krueckeberg.org/notes/d2.html

然而,我在客户端使用I查询排序插件解决了我的问题,jquery datatable和tinysort都很出色: - )

答案 4 :(得分:0)

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

override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)

        NSNotificationCenter.defaultCenter().postNotificationName("stopTimer", object: nil)
    }

<order-by> <order-by-field name="some_field" direction="ASC" /> </order-by> 标记内。