Doctrine2 ArrayCollection - PullRequest
       41

Doctrine2 ArrayCollection

2 голосов
/ 30 января 2011

Хорошо, у меня есть пользовательский объект следующим образом

<?php
class User 
{
    /**
     * @var integer
     * @Id
     * @Column(type="integer")
     * @GeneratedValue
     */
    protected $id;
    /**
     * @var \Application\Entity\Url[]
     * @OneToMany(targetEntity="Url", mappedBy="user", cascade={"persist", "remove"})
     */
    protected $urls;
    public function __construct()
    {
        $this->urls = new \Doctrine\Common\Collections\ArrayCollection();
    }
    public function addUrl($url)
    {
       // This is where I have a problem
    }
}

Теперь я хочу проверить, есть ли у пользователя уже $url в $urls ArrayCollection, перед тем как сохранить$url.

Теперь некоторые примеры, которые я нашел, говорят, что мы должны сделать что-то вроде

if (!$this->getUrls()->contains($url)) {
    // add url
}

, но это не работает, так как сравнивает значения элементов.Так как $url еще не имеет значения id, это всегда будет неудачей, и $url будет дублироваться.

Так что я был бы очень признателен, если бы кто-то мог объяснить, как я могу добавить элемент вArrayCollection без сохранения it и избежания дублирования ?

Edit

Мне удалось добиться этого с помощью

$p = function ($key, $element) use ($url) 
{ 
    if ($element->getUrlHash() == $url->getUrlHash()) { 
        return true; 
    } else { 
        return false; 
    } 
};

Но разве это не загружает все URL, а затем выполняет проверку?Я не думаю, что это эффективно, поскольку на одного пользователя могут приходить тысячи URL.

Ответы [ 2 ]

2 голосов
/ 15 февраля 2011

Это пока невозможно "управляемым доменом" способом, т.е. просто используя объекты. Вы должны выполнить запрос для проверки существования:

SELECT count (u.id) ОТ пользователя u ГДЕ? 1 IN u.urls И u.id =? 2

С Doctrine 2.1 это станет возможным благодаря комбинации двух новых функций:

  1. Extra Lazy Collections
  2. @ IndexBy для коллекций, поэтому вы должны определить @OneToMany (targetEntity = "Url", indexBy = "location")
  3. ExtraLazy Collection Поддержка индекса с помощью -> contains ().

Пункты 1 и 2 уже реализованы в мастере Doctrine 2, но 3 по-прежнему отсутствует.

1 голос
/ 31 января 2011

Вы должны попробовать использовать метод существующие в коллекции и вручную сравнить значения.

...