Doctrine只返回一个可能违反where语句的结果

时间:2016-11-02 20:18:55

标签: php symfony doctrine-orm

我有两个实体ItemProperty OneToMany ManyToOne 关系。

Item.php

/**
 * @ORM\Table(name="Item")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ItemRepository")
 * @ORM\ChangeTrackingPolicy("NOTIFY")
 *
 * @ExclusionPolicy("all")
 */
class Item
    ...
    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\Property", mappedBy="item")
     */
    protected $itemProperties;   

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="createdTs", type="datetime")
     *
     * @Expose
     */
    protected $createdTs;
    ...

Property.php

/**
 * @ORM\Table()
 * @ORM\HasLifecycleCallbacks
 * @ORM\Entity(repositoryClass="AppBundle\Repository\PropertyRepository")
 */
class Property
    ...
    /**
     * @var string
     *
     * @ORM\Column(name="type", type="string", length=255)
     */
    private $type;

    /**
     * @var \AppBundle\Entity\Item
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Item", inversedBy="itemProperties")
     */
    private $item;
    ...

我希望所有早于$date 没有属性实体,其中type的值不可见。

我构建了一个这样的查询:

/**
 * @param \Datetime $date
 * @return array
 */
public function getVisibleItemsOlderThan(\Datetime $date)
{
    $qb = $this->_em->createQueryBuilder();
    $qb->select('i')
        ->from('AppBundle:Item', 'i')
        ->join('i.properties', 'p')
        ->where($qb->expr()->lt('i.createdTs', ':date'))
        ->andWhere('p.type <> :type')
        ->setParameters([
            'date' => $date,
            'type' => 'invisible'
        ]);
    return $qb->getQuery()->getResult();
}

此查询返回一个项,其中属性具有type的值不可见的字段,忽略数据库中的其余项目。

1 个答案:

答案 0 :(得分:1)

我很确定这会有效,尽管可能有更好的方法。

/**
 * @param \Datetime $date
 * @return array
 */
public function getVisibleItemsOlderThan(\Datetime $date)
{
    $qb = $this->_em->createQueryBuilder();
    $qb->select('i')
        ->from('AppBundle:Item', 'i')
        ->leftJoin('i.properties', 'p', 'WITH', 'p.type = :type')
        ->where($qb->expr()->lt('i.createdTs', ':date'))
        ->andWhere('p.id IS NULL')
        ->setParameters([
            'date' => $date,
            'type' => 'invisible'
        ]);
    return $qb->getQuery()->getResult();
}

您可能会发现andWhere('i.properties IS EMPTY')也适用于此。