我有两个具有单向多对一映射的实体。
这是Product
:
use DoctrineCommonCollectionsArrayCollection;
/**
* @Entity
* @Table(name="Product")
* @gedmo:TranslationEntity(class="GPos_Model_Translation_ProductTranslation")
*/
class GPos_Model_Product extends GPos_Doctrine_ActiveEntity {
/**
* @Id @Column(type="integer")
* @GeneratedValue
*/
protected $id;
/**
* @ManyToMany(targetEntity="GPos_Model_Category")
* @JoinTable(name="products_categories",
* joinColumns={@JoinColumn(name="product_id", referencedColumnName="id")},
* inverseJoinColumns={@JoinColumn(name="category_id", referencedColumnName="id")}
* )
*/
protected $categories;
public function __construct() {
$this->categories = new ArrayCollection();
}
public function addCategory(GPos_Model_Category $category) {
if (!$this->categories->contains($category))
$this->categories->add($category);
}
}
如您所见,$categories是GPos_Model_Category实体的 ArrayCollection。
现在怎么办?那么现在我想检索给定类别中的所有产品以及不属于给定类别的所有产品。
我试过$products = GPos_Model_Product::findByCategories($category->getId());
但这只给了我
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '= '1'' at line 1
和$category
的ID是1,所以我想这不是要走的路。有人知道如何处理吗?
谢谢!
多亏了 https://stackoverflow.com/a/9808277/1300454,我终于找到了如何选择类别中的所有产品。
我稍微调整了他的解决方案,以便我可以传递一系列类别实体,它会找到这些类别中的所有产品。如果您提供多个实体,它将返回至少一个给定类别中的任何产品。
这是我的调整(我在我的产品实体中找到了这个函数(:
/**
*
* Takes an array of GPos_Model_Category entities as parameter and returns all products in these categories
* @param array $categories
*/
public static function findByCategories($categories) {
$categoryArray = array();
foreach ($categories as $category) {
array_push($categoryArray, $category->getId());
}
$qb = Zend_Registry::get('entityManager')->createQueryBuilder();
$qb ->select('p')
->from('GPos_Model_Product', 'p')
->leftJoin('p.categories', 'c')
->andWhere($qb->expr()->in('c.id', $categoryArray));
return $qb->getQuery()->execute();;
}
以下是您的称呼:
$products_cat = GPos_Model_Product::findByCategories(array($category));
在这种情况下$category只是一个实体,这就是为什么我在将其提供给函数之前将其放在数组中的原因。
以下是您查找不在给定类别或类别列表中的产品的方法:
/**
*
* Takes an array of GPos_Model_Category entities as parameter and returns all products not in these categories
* @param array $categories
*/
public static function findByNotCategories($categories) {
$categoryArray = array();
foreach ($categories as $category) {
array_push($categoryArray, $category->getId());
}
$qb = Zend_Registry::get('entityManager')->createQueryBuilder();
$qb2 = Zend_Registry::get('entityManager')->createQueryBuilder();
$qb->select('p')
->from('GPos_Model_Product', 'p')
->where($qb->expr()->notIn('p.id',
$qb2->select('p2.id')
->from('GPos_Model_Product', 'p2')
->leftJoin('p2.categories', 'c')
->andWhere($qb->expr()->in('c.id', $categoryArray))
->getDQL()
));
return $qb->getQuery()->execute();
}
这实际上是使用子选择。我正在选择给定类别(即子选择(中的所有产品 ID,然后我选择不在子选择结果中的所有产品。我在这里的工作完成了!