2012-07-14 20 views
17

Al usar doctrine, noté que, para eliminar una entidad, necesito recuperar esa entidad mediante el parámetro dado (nombre, id, etc.) y luego llamar al método remove. Por otro lado, en la consulta, puedo ejecutar la consulta de eliminación.entidad de doctrina eliminar vs eliminar consulta, comparación de rendimiento

Parece que usar el estilo ORM requiere dos operaciones y la operación sql general requiere una operación. Por eso, estoy un poco confundido, si deberíamos usar la operación de eliminación (o actualización) en ORM? ¿No es peor en rendimiento? O hay algo más que me estoy perdiendo? ¿Se puede hacer de otra manera en el estilo ORM?

Respuesta

38

En Doctrine2 puede llamar a la eliminación en un objeto proxy, que no se carga desde la base de datos. Basta con crear un objeto "de prueba", algo así como:

$user = $em->getPartialReference('model\User', array('id' => $id)); 
$em->remove($user); 

No requiere la consulta inicial, pero no estoy muy seguro de si Doctrina todavía lo hace internamente en fush. No lo veo en el SqlLog.

Solo para agregar, creo que este es el comportamiento esperado de cualquier ORM decente. Se trata de objetos y relaciones. Tiene que saber que algo existe antes de eliminarlo. ORM no es solo un generador de consultas . En general, una consulta nativa siempre será más rápida en cualquier ORM. Cualquier ORM agrega una capa de abstracción y lleva tiempo ejecutarla. Es una compensación típica, usted obtiene algunas características sofisticadas y un código limpio, pero pierde algo de rendimiento.

EDIT:

Me alegro de que trabajó para usted. En realidad, me encontré con otro problema, que me hizo darme cuenta de que los proxies y los objetos parciales no son en realidad lo mismo. Los objetos parciales instancian la clase de modelo real y lo llenan con los valores que desea. Después de inicializar un objeto parcial, la carga diferida ya no funciona. Entonces, por ejemplo, si crea un objeto parcial con solo el id, y desea eliminar solo si otro campo de objeto satisface alguna condición, no funcionará, porque ese otro campo siempre será nulo.

Por otro lado, los proxies funcionan con carga lenta y no comparten los problemas que tienen los objetos parciales. Así que me gustaría sugerir fuertemente no utilizar getPartialReference método, en lugar usted puede hacer algo como:

$user = $em->getReference('model\User', $id); 
$em->remove($user); 

El método devuelve el objeto getReference si ya está cargado o un proxy si no lo es. Un proxy puede cargar de forma diferida todos los demás valores si/cuando los necesita. En cuanto a su ejemplo, se comportarán exactamente igual, pero los apoderados seguramente son una mejor forma de hacerlo.

+1

Gracias por la información y la aclaración – Rana

4

¡Hecho! para mí funcionaba así: agregue la línea 3:

$user = $em->getReference('model\User', $id); 
$em->remove($user); 
$em->flush(); 
Cuestiones relacionadas