如何修改自动加载相关实体时使用的查询?

时间:2012-12-17 14:49:05

标签: symfony doctrine-orm

假设有一个非常基本的结构:Category可以包含多个Product项:

/**
 * @ORM\OneToMany(targetEntity="Product", mappedBy="category", cascade="remove")
 */
protected $products;

/**
 * @ORM\ManyToOne(targetEntity="Category", inversedBy="products")
 * @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 */
protected $category;

当我通过类别访问它们时,我得到了所有产品:

$category->products;

假设Product有一个属性invisible。如何强制Doctrine仅加载可见的产品。我在哪里提出此查询?进入存储库?但是:如何调用它或在“加载所有”和“加载确定”之间切换?我当然可以单独请求产品,但这似乎不是一个好的解决方案。

3 个答案:

答案 0 :(得分:1)

在我看来,更好的解决方案是使用Doctrine过滤器(如果您使用的是Doctrine 2.2或更高版本)

Doctrine Filter manual

您可以为不可见属性定义自定义过滤器,并在需要时通过实体管理器启用/禁用它。

答案 1 :(得分:1)

最简单的方法是简单地为您的类别添加可见性参数 - > getProducts()方法:

class Category
{
public function getProducts($invisible = false)
{
    if ($invisible) return $this->products;

    $visibleProducts = array();
    foreach($this->products as $product)
    {
        if ($product->isVisible()) $visibleProducts[] = $product;
    }
    return $visibleProducts;
}

这并不妨碍所有产品的加载,但它确实为您提供了一种简单的方法来决定您想要的产品。而且它很容易实现。您可以稍后进行优化。

第二种方法是创建查询以使用产品加载所有类别。这样可以避免延迟加载产品,并允许您准确指定所需的产品。

最后,您可以按照@ w1cked的建议制作D2过滤器。需要花一点力气来理解这个过程。

答案 2 :(得分:0)

一种解决方案是创建一个“visibleProduct”-Entity,使用单表继承(http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html#single-table-inheritance)并从类别中建立第二个关系。