2

一方向の多対1マッピングを持つ2つのエンティティがあります。

ここにあり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なので、それは行く方法ではないと思います。誰もがそれに対処する方法を知っていますか?

ありがとうございました!

4

1 に答える 1

2

https://stackoverflow.com/a/9808277/1300454のおかげで、カテゴリに含まれるすべての製品を選択する方法がようやくわかりました。

私は彼のソリューションを少し調整して、Category エンティティの配列を渡すことができ、これらのカテゴリ内にあるすべての製品を見つけられるようにしました。複数のエンティティを指定すると、指定されたカテゴリの少なくとも 1 つに含まれる製品が返されます。

これが私の微調整です(この関数は製品エンティティにありました):

/**
 *
 * 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 を選択してから、サブセレクトの結果にないすべての製品を選択しています。ここでの私の仕事は終わりました!

于 2012-05-19T14:45:00.637 に答える