如何使用Doctrine在多对多关系中找到给定值?

时间:2013-09-15 15:19:07

标签: php sql symfony doctrine-orm dql

我有一个实体“讨论”,其中包括:

  • 类别属性(每个讨论都有1个与之关联的类别)
  • ManyToMany“推荐类别”的关联(每个讨论可以推荐多个类别)

我正在尝试选择特定类别(其类别属性是该类别)或此特定类别中推荐的所有讨论。

我可以轻松地获得此类别中的所有讨论:

 $qb = self::$em->getRepository('Discussion')->createQueryBuilder('d');
 $discussions = $qb->where('d.category='.$current_category_id)
 ->setFirstResult( $offset )
 ->setMaxResults( $limit )          
 ->getQuery()->getResult();

我需要在recommended_categories列表中添加所有具有current_category_id的讨论。

所以添加这样的东西:

$qb = self::$em->getRepository('Discussion')->createQueryBuilder('d');
$discussions = $qb->where('d.category='.$current_category_id)

  ->orWhere($qb->expr()->in($current_category_id, 'd.recommended_categories'))

 ->setFirstResult( $offset )
 ->setMaxResults( $limit )          
 ->getQuery()->getResult();

由于它不喜欢SQL中的“4 IN(d.recommended_categories))”而出现SQL错误。

这是在Discussions实体中的recommended_categories:

/**
 * @ManyToMany(targetEntity="Category")
 * @JoinTable(name="discussion_recommended_categories",
 *   joinColumns={@JoinColumn(name="discussion_id", referencedColumnName="id")},
 *   inverseJoinColumns={@JoinColumn(name="category_id", referencedColumnName="id")}
 * )
 */
private $recommended_categories;

这是分类实体:

/** @Id @Column(type="integer") @GeneratedValue **/
protected $id;

/** @Column(type="string", unique=true, nullable=false,name="Name") **/
protected $name;

我也试过玩弄存在(d.recommended_categories中存在$ current_category_id)但没有任何效果。

有关如何检查与该实体关联的值列表中是否存在给定值(不是列)的任何想法?

谢谢!

1 个答案:

答案 0 :(得分:1)

首先,您应该在where子句中使用prepared statements作为参数,这样就可以防止sql注入。此外,您需要传入当前的类别实体,并且Doctrine将通过查看您的映射神奇地从中提取id。假设您有$currentCategory可用。

$discussions = $qb
    ->where('d.category = :category')
    ->setParameter('category', $currentCategory);

您正在尝试使用IN检查集合中的给定值,但这不是IN的含义。你应该将它用于one of条件(作为几个或几个的替代)。即myfield = 1或myfield = 2或myfield = 3你可以写为myfield IN(1,2,3)。 我认为你有一个语法错误,因为你的参数顺序错误。

无论如何摆脱IN只是添加一个join_categories和一个orWhere类别的连接。总而言之,你应该最终得到类似的东西......未经测试。

$discussions = $qb
    ->where('d.category = :category')
    ->leftJoin('d.recommended_categories', 'rc')
    ->orWhere('rc = :category')
    ->setParameter('category', $currentCategory);