2009-08-24 11 views

Respuesta

27

Si está utilizando la carga diferida, Cargar solo crea un proxy.

session.Delete(session.Load(type, id)); 

Con NH 2.1 puede usar HQL. No estoy seguro de cómo realmente se parece, pero algo como esto: nota de que esto está sujeto a la inyección SQL - si es posible utilizar parametrizada dudas en lugar de setParameter()

session.Delete(string.Format("from {0} where id = {1}", type, id)); 

Editar:

Para carga, no es necesario que sepa el nombre de la columna Id.

Si lo que necesita saber que, lo puede conseguir por los metadatos NH:

sessionFactory.GetClassMetadata(type).IdentifierPropertyName 

Otra edición.

session.Delete() se instanciar la entidad

Al utilizar Session.delete(), NH carga la entidad de todos modos. Al principio no me gustó. Entonces me di cuenta de las ventajas. Si la entidad es parte de una estructura compleja que usa herencia, colecciones o "cualquier" referencia, en realidad es más eficiente.

Por ejemplo, si la clase A y B tanto heredan de Base, que no trata de eliminar datos del cuadro B cuando la entidad real es de tipo A. Esto no sería posible sin cargar el objeto real. Esto es particularmente importante cuando hay muchos tipos heredados que también constan de muchas tablas adicionales cada uno.

Se da la misma situación cuando tiene una colección de Base s, que son todas las instancias de A. Al cargar la colección en la memoria, NH sabe que no es necesario eliminar ningún artículo B.

Si la entidad A tiene una colección de B s, que contiene C s (y así sucesivamente), no intente eliminar cualquier C s cuando está vacía la colección de B s. Esto solo es posible al leer la colección. Esto es particularmente importante cuando C es complejo por sí mismo, agregando incluso más tablas, etc.

Cuanto más compleja y dinámica es la estructura, más eficiente es cargar datos reales en lugar de eliminarlos "ciegamente".

HQL Elimina tienen dificultades

HQL elimina para no cargar datos en la memoria. Pero las eliminaciones de HQL no son tan inteligentes. Básicamente, traducen el nombre de la entidad al nombre de la tabla correspondiente y lo eliminan de la base de datos. Además, elimina algunos datos de recopilación agregados.

En estructuras simples, esto puede funcionar bien y eficiente. En estructuras complejas, no todo se elimina, lo que lleva a violaciones de restricciones o "pérdidas de memoria en la base de datos".

Conclusión

I también trató de optimizar su eliminación con NH. Me rendí en la mayoría de los casos, porque NH todavía es más inteligente, "simplemente funciona" y suele ser lo suficientemente rápido. Uno de los algoritmos de eliminación más complejos que escribí es analizar las definiciones de asignación de NH y crear declaraciones de eliminación a partir de eso. Y, no es sorpresa, no es posible sin leer los datos de la base de datos antes de eliminarlos. (Acabo de reducirlo para que solo cargue las claves primarias.)

+0

Bien, pero no puedo usar este código tal como está, porque asume que sé el nombre de la columna Id, lo cual no es cierto. ¿Es posible, dado el tipo de CLR de entidad real, ubicar el nombre de la columna Id? Después de todo, está en el mapeo. Luego, después de obtener el nombre de la columna Id, podría ejecutar el HQL. Gracias – mark

+1

Ver mis notas adicionales. –

+0

Casi allí, pero todavía hay un problema. Algunas entidades definen el nombre de la entidad en su mapeo, pero no todas. El tipo de entidad siempre se conoce. El problema es que GetClassMetadata devuelve nulo cuando se le asigna el tipo de entidad que define el nombre-entidad en su mapeo. Entonces, obtengo nulo cuando llamo a sessionFactory.GetClassMetadata (tipo). ¿Qué voy a hacer? Gracias. – mark

Cuestiones relacionadas