所以我有一个基本的博客,包含文章(AppBundle\Entity\Courrier)和评论(AppBundle\Entity\Reaction)。这两个实体通过OneToMany关系绑定在一起。以下是它们的定义:
Courrier.php
<?php
namespace AppBundle\Entity;
class Courrier
{
// ...
/**
*
* @ORM\OneToMany(targetEntity="Reaction", mappedBy="courrier")
*/
private $reactions;Reaction.php
<?php
namespace AppBundle\Entity;
class Reaction
{
const STATUS_ACCEPTED = 0;
const STATUS_PENDING = 1;
const STATUS_MODERATED = 2;
const STATUS_TRASHED = 3;
// ...
/**
* Thread of this comment
*
* @var Courrier
* @ORM\ManyToOne(targetEntity="Courrier", inversedBy="reactions")
* @ORM\JoinColumn(name="courrier_id", referencedColumnName="id")
*/
private $courrier;使用
/**
* @var integer
*
* @ORM\Column(name="status", type="integer")
*/
private $status;我的问题是,当我查询AppBundle:Courrier存储库时,我想要过滤基于$status的AppBundle:Reaction。这意味着要做这样的事情:
$courrier = $doctrine->getRepository('AppBundle:Courrier')->findOneWithReactionsFiltered($slugCourrier, Reaction::STATUS_ACCEPTED)因此,我构建了这个存储库方法,如下所示:
public function findOneWithReactionsFiltered($slug, $status)
{
return $this->createQueryBuilder('c')
->leftJoin('c.reactions', 'r')
->where('c.slug = :slug')
->andWhere('r.status = :status')
->setParameters([
'slug' => $slug,
'status' => $status,
])
->getQuery()
->getOneOrNullResult()
;
}但是,此方法的返回值(即$courrier)是用Courrier实体填充的,其Reactions与$status无关。
我还转储了SQL查询:
SELECT c0_.id AS id0, c0_.name AS name1, c0_.slug AS slug2, c0_.envoi AS envoi3, c0_.intro AS intro4, c0_.courrier AS courrier5, c0_.reponse AS reponse6, c0_.published AS published7, c0_.like_count AS like_count8, c0_.recu AS recu9, c0_.image_id AS image_id10, c0_.categorie_id AS categorie_id11 FROM courrier c0_ LEFT JOIN reaction r1_ ON c0_.id = r1_.courrier_id WHERE c0_.slug = 'yaourt-cerise' AND r1_.status = 0;最后,这里是表的一个小转储:
mysql> select r.id, r.status, c.slug from reaction as r left join courrier as c on c.id = r.courrier_id order by c.slug asc;
+-------+--------+------------------------------------+
| id | status | slug |
+-------+--------+------------------------------------+
| 15533 | 1 | yaourt-cerise |
| 15534 | 1 | yaourt-cerise |
| 15535 | 1 | yaourt-cerise |
| 15536 | 1 | yaourt-cerise |
| 15537 | 1 | yaourt-cerise |
| 15538 | 1 | yaourt-cerise |
| 15539 | 1 | yaourt-cerise |
| 15540 | 1 | yaourt-cerise |
| 15541 | 1 | yaourt-cerise |
| 15526 | 0 | yaourt-cerise |
| 15542 | 1 | yaourt-cerise |
| 15527 | 1 | yaourt-cerise |
| 15543 | 1 | yaourt-cerise |
| 15528 | 1 | yaourt-cerise |
| 15544 | 1 | yaourt-cerise |
| 15529 | 1 | yaourt-cerise |
| 15545 | 1 | yaourt-cerise |
| 15530 | 1 | yaourt-cerise |
| 15546 | 1 | yaourt-cerise |
| 15531 | 1 | yaourt-cerise |
+-------+--------+------------------------------------+ 有人能帮忙吗?
发布于 2016-05-15 19:53:46
您需要选择这两个实体水合物,然后进入集合上的查询。
例如,需要为r别名添加另一个select:
->addSelect('r')然后,您的集合将正确加载并从查询中筛选。
欲了解更多信息,请参见下面的答案:
Filtering of associated entity collection in Symfony / Doctrine
发布于 2016-05-15 19:07:56
这是故意的行为。通过查询Courrier存储库,您将得到至少有一个具有所提供状态的Reaction的实体。Reactions并没有立即加入,但是您从存储库获得的Doctrine代理一旦访问它的$reaction ArrayCollection就会全部获取它们。
你可以通过两种方式得到你想要的东西:
Reaction存储库并在那里执行查询,可能加入Courrier使您不必再对其进行查询;Courrier实体中创建一个方法,根据标准筛选集合结果。可能是这样的:
公共函数Criteria::create()->where(Criteria::expr()->eq('status',getReactionsWithStatus($status) {返回$this-> return >matching($status$status);)->toArray();}注意:以下是这个问题演变为以来的过时回答
在替换参数时,应该在没有冒号的情况下传递它们。变化
->setParameter(':courrier', $value)至
->setParameter('courrier', $value)你应该可以走了。
不要忘记为reaction做同样的事情。
https://stackoverflow.com/questions/37242447
复制相似问题