Symfony 应用相关标准

Symfony apply criteria in relation

我有一个名为 Products

的实体
<?php
class Product
{
    /**
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Product", inversedBy="list")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="id_parent", referencedColumnName="id", nullable=true)
     * })
     */
    private $parent;

    /**
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\Product", 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() 它会检索所有子产品,而我只需要检索具有 [=41= 的子产品] 不是空字符串。

有没有办法将所有特定条件应用于查询的完整结果,或者以某种方式将参数传递给 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 : []
}

有时我只需要检索所有产品,有时我只需要那些 是 active = 1.

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

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

之后

Doctrine 为您提供的列表 ($this->list) 是一个 ArrayCollection,其中包含 matching 用于 return 过滤实体集的方法。

您必须向它传递一个 Criteria 对象,例如:

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

这将 return 来自 $this->list->myField 等于 $myParam

的所有实体

更多信息在这里: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();