我正在尝试根据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")
如何访问相关对象?
答案 0 :(得分:9)
我查看了源代码Criteria::expr()->eq("name", --- second value ---)
。第二个值需要Doctrine\Common\Collections\Expr\Value
的实例。因此,不可能在其中放置另一个Expr
或criteria
。只有Expr
And
和Or
会占用另一个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
实现非常轻,他们可能希望保持这种状态。