Doctrine2 ArrayCollection [英] Doctrine2 ArrayCollection
问题描述
好的,我有一个用户实体如下
Ok, I have a User entity as follows
<?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 $ c在$ code> $ urls
ArrayCollection
之前$ c $ $ $ url
。
Now, what I want to do is check if the User has already the $url
in the $urls
ArrayCollection
before persisting the $url
.
现在我发现的一些例子说明我们应该做些类似于
Now some of the examples I found says we should do something like
if (!$this->getUrls()->contains($url)) {
// add url
}
但这不起作用,因为这比较了元素值。由于 $ url
还没有 id
的价值,这将永远失败, $ url
将被公开。
but this doesn't work as this compares the element values. As the $url
doesn't have id
value yet, this will always fail and $url
will be dublicated.
所以我真的很感激,如果有人可以解释如何添加一个元素到ArrayCollection 没有
So I'd really appreciate if someone could explain how I can add an element to the ArrayCollection without persisting it and avoiding the duplication?
修改
我已经设法通过
$p = function ($key, $element) use ($url)
{
if ($element->getUrlHash() == $url->getUrlHash()) {
return true;
} else {
return false;
}
};
但是这个还没有加载所有的URL,然后执行检查?我不认为这是有效的,因为每个用户可能有数千个URL。
But doesn't this still load all urls and then performs the check? I don't think this is efficient as there might be thousands of urls per user.
推荐答案
这是不可能的域驱动的方式,即只是使用对象。您应该执行一个查询来检查存在:
This is not yet possible in a "domain driven" way, ie. just using objects. You should execute a query to check for the existance:
SELECT count(u.id)FROM User u WHERE?1 IN u.urls AND u.id =?2
SELECT count(u.id) FROM User u WHERE ?1 IN u.urls AND u.id = ?2
使用Doctrine 2.1可以使用两个新功能的组合:
With Doctrine 2.1 this will be possible using a combination of two new features:
- 额外的懒惰集合
- @IndexBy用于集合,因此您可以定义@OneToMany(targetEntity =Url,indexBy =location)
- ExtraLazy Collection通过使用 - > contains()来支持索引。
点1和2已经在Doctrine 2主程序中实现,但3仍然缺少。
Points 1 and 2 are already implemented in Doctrine 2 master, but 3 is still missing.
这篇关于Doctrine2 ArrayCollection的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!