Doctrine2 ArrayCollection

时间:2011-01-29 22:56:56

标签: lazy-loading doctrine-orm arraycollection

好的,我有一个如下的用户实体

<?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 添加元素而不坚持 并避免重复

修改

我已经设法通过

实现了这个目标
$p = function ($key, $element) use ($url) 
{ 
    if ($element->getUrlHash() == $url->getUrlHash()) { 
        return true; 
    } else { 
        return false; 
    } 
};

但是这还没有加载所有网址然后执行检查吗?我不认为这是有效的,因为每个用户可能有数千个网址。

2 个答案:

答案 0 :(得分:2)

这在“域驱动”方式中尚不可能,即。只是使用对象。您应该执行查询以检查是否存在:

SELECT count(u.id)FROM User u WHERE?1 IN u.urls AND u.id =?2

使用Doctrine 2.1,可以使用两个新功能的组合:

  1. Extra Lazy Collections
  2. @IndexBy for collections,所以你要定义@OneToMany(targetEntity =“Url”,indexBy =“location”)
  3. ExtraLazy Collection使用 - &gt; contains()。
  4. 支持索引

    第1点和第2点已经在Doctrine 2 master中实现,但仍然缺少3点。

答案 1 :(得分:1)

您应该尝试在集合上使用exists方法并手动比较值。