【问题标题】:Doctrine2 findby on a Many-to-One mapping多对一映射上的 Doctrine2 findby
【发布时间】:2012-05-18 12:51:32
【问题描述】:

我有两个具有单向多对一映射的实体。

这里是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);
    }
}

如您所见,$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,所以我想这不是要走的路。有人知道如何处理吗?

谢谢!

【问题讨论】:

    标签: doctrine-orm many-to-one arraycollection findby


    【解决方案1】:

    感谢https://stackoverflow.com/a/9808277/1300454,我终于知道了如何选择一个类别中的所有产品。

    我稍微调整了他的解决方案,这样我就可以传递一个类别实体数组,它会找到这些类别中的所有产品。如果您提供多个实体,它将返回至少属于给定类别之一的任何产品。

    这是我的调整(我在我的 Product 实体中找到了这个函数):

    /**
     *
     * 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(即子选择),然后选择不在子选择结果中的所有产品。我的工作已经完成了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-18
      • 1970-01-01
      • 2012-10-18
      • 2017-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多