Symfony2-Doctrine Выбор данных с WHERE из DoctrineArray

В сущности у меня есть поле, которое выглядит так:

/**
 * @ORM\Column(type="array")
 */
protected $category;

и QueryBuilder

$qb = $this->createQueryBuilder('s');
$qb->select($fields)
    ->where( 's.category IN (:category)') //////////// <----
    ->orderBy('s.name', 'ASC')
    ->setParameter('category', $category_id);

Таким образом, в категории полей базы данных находится Doctrine2 Array. Я хочу выбрать записи из базы данных с помощью QueryBuilder. Мой вопрос: как я могу это сделать с предложением WHERE, которое будет проверять поля из этого массива?


person user2604244    schedule 20.08.2013    source источник
comment
Неа. Вы не можете запрашивать значения массива. Если вы проверите свою базу данных, вы увидите, что она на самом деле хранится в виде строки. Тип массива является расширением доктрины для сохраняемых массивов. Сама база данных о них ничего не знает. Если вы хотите выполнять такие запросы, вам нужно создать объект с именем «Категория» со своей собственной таблицей и связать его с вашим основным объектом.   -  person Cerad    schedule 20.08.2013


Ответы (2)


Посмотрите здесь. ты

// Instead, use $qb->expr()->in('value', array('?1')) and bind your parameter to ?1 (see section above)
public function in($x, $y); // Returns Expr\Func instance
person Thierry    schedule 27.08.2013

@Cerad дал вам совершенно правильный комментарий. Одна из проблем хранения массивов заключается в том, что у вас нет возможности поиска.

См. PHP/MySQL - Хранение массива в базе данных и Хранение массивов в базе данных. Как видите, это ужасная практика.

Лучший способ — просто создать объект категории и установить отношение OneToMany с этой категорией.

Вот пример сущности Книга, которая имеет много категорий:

1 Создайте объект категории:

class Category implements CategoryInterface
{
    //.....

    /**
     * Title of the category
     *
     * @ORM\Column(type="string", length=100)
     */
    protected $title;

    /**
     * Relation with your book entity for example
     *
     * @ORM\ManyToOne(targetEntity="Book", inversedBy="categories")
     * @ORM\JoinColumn(name="book_id", referencedColumnName="id")
     */
    private $book;

    /**
     * Set book
     *
     * @param BookInterface $book
     */
    public function setBook(BookInterface $book)
    {
        $this->book = $book;
    }

    /**
     * Get book
     *
     * @return BookInterface
     */
    public function getBook()
    {
        return $this->book;
    }


}

2 Ваша книга:

use Doctrine\Common\Collections\ArrayCollection;

class Book implements BookInterface
{
    /**
     * Categories for the books
     *
     * @ORM\OneToMany(targetEntity="Category", mappedBy="book")
     * @var CategoryInterface[]
     */
    protected $categories ; 

    public function __construct()
    {
        $this->categories = new ArrayCollection();
    }

   /**
     * Add Categories
     *
     * @param CategoryInterface $category
     */
    public function addCategory(CategoryInterface $category)
    {
        $category->setBook($this);
        $this->categories->add($category);
    }

    /**
     * Remove Category
     *
     * @param CategoryInterface $category
     * @return bool
     */
    public function removeCategory(CategoryInterface $category)
    {
        return $this->categories->removeElement($category);
    }

    /**
     * Get Categories
     *
     * @return Doctrine\Common\Collections\Collection
     */
    public function getCategories()
    {
        return $this->categories;
    }

    /**
     * Set Categories
     *
     * @param ArrayCollection $categories
     */
    public function setCategories($categories) {

        $this->categories->clear();

        foreach ($categories as $category) {
            $this->addCategory($category);
        }

        return $this;
    }

3 Теперь вы можете правильно искать.

person Mick    schedule 27.08.2013