lazy-loading - arraycollection php
Doctrine2 ArrayCollection (2)
Ok, tengo una entidad de Usuario de la siguiente manera
<?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
}
}
Ahora, lo que quiero hacer es verificar si el usuario ya tiene el $url
en $urls
ArrayCollection
antes de persistir el $url
.
Ahora, algunos de los ejemplos que encontré dicen que deberíamos hacer algo como
if (!$this->getUrls()->contains($url)) {
// add url
}
pero esto no funciona, ya que esto compara los valores de los elementos. Como $url
aún no tiene valor de id
, esto siempre fallará y $url
se duplicará.
Entonces, realmente agradecería que alguien pudiera explicar cómo puedo agregar un elemento a ArrayCollection sin persistir y evitar la duplicación .
Editar
He logrado lograr esto a través de
$p = function ($key, $element) use ($url)
{
if ($element->getUrlHash() == $url->getUrlHash()) {
return true;
} else {
return false;
}
};
Pero, ¿esto todavía no carga todas las URL y luego realiza el control? No creo que esto sea eficiente, ya que puede haber miles de URL por usuario.
Debe intentar usar el método exists en la colección y comparar valores manualmente.
Esto aún no es posible de una manera "controlada por el dominio", es decir. solo usando objetos. Debe ejecutar una consulta para verificar la existencia:
SELECCIONAR conteo (u.id) DE Usuario u DONDE? 1 IN u.urls AND u.id =? 2
Con Doctrine 2.1 esto será posible usando una combinación de dos nuevas funciones:
- Colecciones Extra Lazy
- @IndexBy para colecciones, por lo que definiría @OneToMany (targetEntity = "Url", indexBy = "ubicación")
- Soporte de ExtraLazy Collection para index usando -> contains ().
Los puntos 1 y 2 ya están implementados en el maestro de Doctrine 2, pero todavía faltan 3.