我能在使用Doctrine 2的延迟加载时过滤掉arrayCollection中的结果吗?例如:
// users = ArrayCollection with User entities containing an "active" property
$customer->users->filter('active' => TRUE)->first()
我不太清楚filter方法实际上是如何使用的。
我能在使用Doctrine 2的延迟加载时过滤掉arrayCollection中的结果吗?例如:
// users = ArrayCollection with User entities containing an "active" property
$customer->users->filter('active' => TRUE)->first()
我不太清楚filter方法实际上是如何使用的。
Doctrine现在有Criteria
,它提供了一个单一的API,可以根据上下文使用SQL和PHP来过滤集合。
更新
使用这种方法可以在不从数据库获取所有内容的情况下实现接受答案中的结果。
use Doctrine\Common\Collections\Criteria;
/**
* @ORM\Entity
*/
class Member {
// ...
public function getCommentsFiltered($ids) {
$criteria = Criteria::create()->where(Criteria::expr()->in("id", $ids));
return $this->getComments()->matching($criteria);
}
}
indexBy="xxx"
对集合进行索引并调用 matching
时,似乎存在问题,其中索引会被丢弃。https://github.com/doctrine/doctrine2/issues/4693 - Will B.fetch="EXTRA_LAZY"
声明关系时,Criteria
才能像预期的那样工作(使用SQL而不是通过PHP进行过滤)。然而,并非每个关系都适用于fetch="EXTRA_LAZY"
...http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/extra-lazy-associations.html - V-Light这篇文章中Boris Guéry的回答可能会对你有所帮助:Doctrine 2, query inside entities
$idsToFilter = array(1,2,3,4);
$member->getComments()->filter(
function($entry) use ($idsToFilter) {
return in_array($entry->getId(), $idsToFilter);
}
);
Criteria
的回答现在(2014年)应该被接受为正确答案,因为它可以在SQL层面过滤集合。 - jcbwlkr您的使用情境将是:
$ArrayCollectionOfActiveUsers = $customer->users->filter(function($user) {
return $user->getActive() === TRUE;
});
如果您添加 ->first(),您将仅获取返回的第一条记录,这不是您想要的。
@Sjwdavies 您需要在传递给 USE 的变量周围加上括号。您还可以缩短代码,因为 in_array 返回一个布尔值:
$member->getComments()->filter( function($entry) use ($idsToFilter) {
return in_array($entry->getId(), $idsToFilter);
});
//$customer = ArrayCollection of customers;
$customer->getUsers()->filter(
function (User $user) {
return $user->getActive() === true;
}
);
Collection#filter
方法确实会预先加载所有成员。
在Doctrine 2.3中将添加在SQL级别进行过滤的功能。