我在Symfony PersistentCollection
中苦苦挣扎-在存储库上执行的查询findByOne()
的结果集中。我需要根据PersistentCollection
中的特定值来查找一个或多个元素,即与另一个与另一个有关系的实体。
我有一个与RuleSet
实体有关的SrcFile
实体。
在RuleSetRepository
上,我调用方法findOneBy(['id' => 1)
以找到RuleSet ID = 1。
这将返回具有RuleSet
的对象srcFiles: PersistentCollection
。
现在我需要从该集合中获取特定对象。我知道有一种方法getIterator()
,我可以遍历集合中的所有结果,并建立条件来查找文件。kind=='master',但是...
是否有更好的方法使用buildin方法在PersistentCollection中访问/查找/搜索?
//...
// dump of acctual result of
dump($grsr->findOneBy(['id' => 1)]);
// dumped data (shortened version):
ProfileUController.php on line 118:
RuleSet {#1509 ▼
-id: 1
-srcFiles: PersistentCollection {#1507 ▼
-snapshot: array:5 [ …5]
-owner: RuleSet {#1509}
-association: array:15 [ …15]
-em: EntityManager {#975 …11}
-backRefFieldName: "ruleset"
-typeClass: ClassMetadata {#1230 …}
-isDirty: false
#collection: ArrayCollection {#1481 ▼
-elements: array:5 [▼
0 => SrcFile {#1573 ▶}
1 => SrcFile {#1734 ▶}
//...
]
}
#initialized: true
}
}
答案 0 :(得分:0)
您要寻找的是Doctrine Criteria
,它使您可以过滤Collection
。如果收集对象还没有在内存中,它可以在数据库级别进行筛选足够聪明。
这是一个简单的例子:
$ruleSet = $grsr->findOneBy(['id' => 1]);
$criteria = Criteria::create();
// Criteria to find SrcFiles where kind = 'master'
$criteria->where(Criteria::expr()->eq('kind', 'master');
// return only the srcFiles matching criteria
$ruleSet->srcFiles->matching($criteria);
我更喜欢在我的实体上创建辅助方法,因为我认为它更清洁一些。这取决于您,但是我会在RuleSet
实体上做类似的事情:
public function getMasterFiles()
{
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('kind', 'master');
// assuming you have a getter named getSrcFiles for the srcFiles association
return $this->getSrcFiles()->matching($criteria);
}
然后您可以执行类似的操作(并且不必在每次我们需要主文件时都重复代码):
$ruleSet = $grsr->findOneBy(['id' => 1]);
$ruleSet->getMasterFiles();
更新
如果需要过滤嵌套集合,则必须使用filter
方法:
public function getMasterFiles()
{
return $this->getSrcFiles()->filter(function(SrcFile $srcFile) {
// if callback returns true, then object is included in result
return ($srcFile->getKind() === 'master' && $srcFile->getSrcSheet()->getName() === 'MainData');
});
}
filter
方法更灵活,但是始终在从数据库中获取对象之后对对象进行处理。通常这没什么大不了的,但是会影响性能。另一个选项是自定义存储库方法,但我更喜欢在实体上使用辅助方法。对我来说,感觉更像是ORMish。