学说2.3标准。访问相关对象

时间:2013-08-09 16:38:03

标签: symfony doctrine-orm criteria

我正在尝试根据the Doctrine Docs设置标准。

不幸的是,他们没有告诉您如何访问相关对象的属性。我举个例子。

我有一个产品的ArrayCollection。每个产品都有一个类别。我想过滤类别名称的ArrayCollection。现在我正在尝试按如下方式设置标准:

$criteria = Criteria::create()
  ->where(Criteria::expr()->eq("category.name", "SomeCategoryName"));

现在我得到以下例外:

An exception has been thrown during the rendering of a template ("Unrecognized field: category.name")

如何访问相关对象?

2 个答案:

答案 0 :(得分:9)

我查看了源代码Criteria::expr()->eq("name", --- second value ---)。第二个值需要Doctrine\Common\Collections\Expr\Value的实例。因此,不可能在其中放置另一个Exprcriteria。只有Expr AndOr会占用另一个Expr。 我很确定你想用其他函数解决这个问题,比如filter()或者用getIterator()得到一个迭代器。这就是使用filter()方法完成的方法。

$filteredProducts = 
    $products->filter(function($key, $element) use ($categoryName) {
        return $element->getCategory()->getName() === categoryName;
    });

如果每个下一个关系都可以Iterator,那么可以嵌套foreach循环并在其中进行过滤。

答案 1 :(得分:3)

这可能属于存储库方法,而不是过滤器方法。如果您希望在父对象(如Order或其他)上的集合中获取预过滤的Products列表,则可以在查询构建器中过滤子集合。但是,你必须处理没有完全水合物的可能令人困惑的副作用。

这应该会为您提供Order个对象的列表,这些对象只有Product个孩子与类别名称匹配。

class OrderRepository extends EntityRepository {
  public function findOrderWithProductCategory($category)
  {
    $builder = $this->createQueryBuilder('o')
      ->select('o, p')
      ->leftJoin('o.products', 'p')
      ->join('p.category', 'c', 'WITH', 'c.name = :category')
      ->setParameter('category', $category);
  }
}

如果您不知道以后会对哪种类别感兴趣,那么无论如何您最好使用@ Flip的解决方案,并为所有类别预先保湿。使用partial hydration和标准ArrayCollection::filter()闭包,在大多数情况下表现相当不错。

那就是说,作为一个功能,这将是相当不错的。我怀疑Doctrine的人会不情愿,因为目前的Criteria实现非常轻,他们可能希望保持这种状态。