2

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

<?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; 
    } 
};

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

4

2 回答 2

2

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

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

在 Doctrine 2.1 中,这将使用两个新特性的组合来实现:

  1. 额外的懒惰收藏
  2. @IndexBy 用于集合,因此您将定义 @OneToMany(targetEntity="Url", indexBy="location")
  3. 使用 ->contains() 对索引的 ExtraLazy 集合支持。

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

于 2011-02-14T23:18:24.790 回答
1

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

于 2011-01-31T03:57:56.410 回答