Symfony在关系中应用标准



我有一个名为Products的实体

<?php
class Product
{
/**
* @ORMColumn(name="id", type="integer")
* @ORMId
* @ORMGeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @ORMManyToOne(targetEntity="AppBundleEntityProduct", inversedBy="list")
* @ORMJoinColumns({
*   @ORMJoinColumn(name="id_parent", referencedColumnName="id", nullable=true)
* })
*/
private $parent;
/**
* @ORMOneToMany(targetEntity="AppBundleEntityProduct", mappedBy="parent")
*/
private $list;
//... more properties
}

getList方法是这样的:

public function getList()
{
if($this->list !== null){
return $this->list->getValues();
}
}

现在,在控制器中我遇到了问题,有时我需要按同一实体的属性过滤列表,有时我需要它没有过滤器。

我使用 dql 创建查询:

$query = "SELECT p
FROM AppBundle:Product p
WHERE (p.parent= 0 OR p.parent IS NULL)
AND p.code != '' ";
$createdQuery= $this->em->createQuery($query)->setParameters($params);
$result= $createdQuery->getResult();

查询产生的产品具有正确的数据,但是如果我尝试打印$products[0]->getList()它会检索所有子产品,并且我只需要检索具有 p.code 而不是空白字符串的产品。

有没有办法将所有特定条件应用于查询的完整结果,或者以某种方式将参数传递给getList()方法以将逻辑应用于该方法,以有时筛选列表的结果,有时不筛选列表?

更新

我从数据库中检索的数据示例:

Product 1
{
id : 1,
parent : null,
code: 'aa',
list : [
Product 2
{
id : 2,
parent : object with the product 1,
code: '',
list : []
}
]
}
Product 3
{
id : 3,
parent : null,
code: 'bb',
list : []
}

有时我只需要检索所有产品,有时我只需要那些女巫处于活动状态= 1。

使用示例中的查询,我正确检索了所有产品,但AND p.code != ''仅适用于根目录中的产品。我想将此过滤器应用于列表属性,但并非总是如此。

您可以在从数据库中检索所有数据后或在查询期间执行此操作。

Doctrine 为您提供的列表 ($this->list( 是一个ArrayCollection,其中包含一个返回一组过滤实体的matching方法。

您必须向其传递一个Criteria对象,如下所示:

public function getList($myParam = null)
{
if ($myParam) {
$crit = Criteria::create();
$crit->andWhere(Criteria::expr()->eq('myField', $myParam));
return $this->list->matching($crit)->getValues();
}
}

这将返回->myField等于$myParam$this->list的所有实体

更多信息在这里: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/working-with-associations.html#filtering-collections

您还可以通过使用 Join 和额外条件修改查询来直接筛选关联的结果:

$query = "SELECT p
FROM AppBundle:Product p
LEFT JOIN p.list child WITH child.active = :active
WHERE (p.parent= 0 OR p.parent IS NULL)
AND p.code != ''";
$createdQuery= $this->em->createQuery($query)->setParameters([
'active' => 1
]);
$result= $createdQuery->getResult();

您还可以使用QueryBuilder有条件地修改查询(如果您执行Doctrine,则不会错过该内容(:

$queryBuilder = $this->em->createQueryBuilder()
->from('AppBundle:Product', 'p')
->where('(p.parent= 0 OR p.parent IS NULL) AND p.code != ""');
if ($onlyActive)
$queryBuilder
->leftJoin('p.list', 'child', 'child.active = :active')
->setParameter('active', 1);
$result = $queryBuilder->getQuery()->getResult();

最新更新