2012-05-18 69 views
2

我有兩個具有單向多對一映射的實體。在多對一映射下的Doctrine2 findby

這裏的Product

use Doctrine\Common\Collections\ArrayCollection; 

/** 
* @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); 
    } 
} 

正如你可以看到,$類是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,所以我想這不是要走的路。任何人都知道如何處理?

謝謝!

回答

2

我終於找到了如何選擇歸類於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)); 

在這種情況下$類是單獨的實體,這就是爲什麼我在將它賦予函數之前,將它放入數組中。

這裏是你發現沒有類別的特定類別或產品列表的方式:

/** 
* 
* 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(這是子選擇),然後選擇所有不在子選擇結果中的產品。我的工作已經完成!