2010-10-04 12 views
11

Estoy tratando de averiguar por qué NHibernate maneja cascadas de uno a muchos (usando cascade = all-delete-huérfano) de la manera en que lo hace. Me encontré con el mismo problema que este individuo:¿Por qué NHibernate elimina huérfanos primero?

Forcing NHibernate to cascade delete before inserts

Por lo que yo puedo decir NHibernate siempre realiza inserciones en primer lugar, a continuación, actualiza, a continuación, elimina. Puede haber una muy buena razón para esto, pero no puedo, por la vida de mí, descubrir cuál es esa razón. Espero que una mejor comprensión de esto me ayude a encontrar una solución que no odie :)

¿Hay alguna buena teoría sobre este comportamiento? ¿En qué escenario eliminaría primero a los huérfanos? ¿Funcionan todos los ORM de esta manera?

+1

Solo quiero añadir mi frustración a esta pregunta. NHibernate es una falla absoluta en este caso. He estado luchando todo el día con este estúpido problema. Incluso los ORM más básicos manejan esto mucho más elegantemente que NHibernate. Terminé teniendo que codificar completamente esto.Usted y yo debemos habernos perdido algo. – JasonCoder

Respuesta

2

EDIT: Después de decir que no hay razón, aquí hay un motivo. Digamos que tiene el siguiente escenario:

public class Dog { 
    public DogLeg StrongestLeg {get;set;} 
    public IList<DogLeg> Legs {get;set; 
} 

Si se va a eliminar en primer lugar, y digamos que elimina todos Dog.Legs, entonces es posible eliminar la StrongestLeg lo que causaría una violación de referencia. Por lo tanto, no puede BORRAR antes de ACTUALIZAR.

Digamos que agrega una nueva pata, y esa nueva pata también es la StrongestLeg. Luego debe INSERTAR antes de ACTUALIZAR para que la Pierna tenga una Id que pueda insertarse en Dog.StrongestLegId.

Por lo tanto, debe INSERTAR, ACTUALIZAR y, a continuación, ELIMINAR.

También como nHibernate está basado en Hibernate, eché un vistazo a Hibernate y encontré a varias personas hablando sobre el mismo problema.

Y aquí es la mejor respuesta de ellos:

Gail Badner agregó un comentario - 21/Feb/08 2:30 PM: El problema surge cuando se agrega a la colección una nueva entidad de asociación con un ID generado . El primer paso , al fusionar una entidad que contiene esta colección, es en cascada guarda la nueva asociación entidad. La cascada debe ocurrir antes de otros cambios en la colección. Dado que la clave única para esta nueva entidad de asociación es la misma que una entidad que ya se ha conservado, se genera una RestricciónViolaciónExtensiva . Este es el comportamiento esperado.

+0

No es solo este caso. Básicamente, cualquier entidad a la que se hace referencia no se puede eliminar hasta que se elimine la referencia. Cualquier entidad que haga referencia a otra no puede actualizarse hasta que la otra se inserte. – Iain

+0

Algunos RDBMS permiten diferir la verificación de restricciones hasta el final de la transacción, por lo que no es una pregunta no razonable, y un escenario muy válido y común. Más información http://stackoverflow.com/questions/1330020/is-it-possible-to-defer-referential-integrity-checks-until-the-end-of-a-transact – ironstone13

Cuestiones relacionadas