2008-12-05 18 views
10

Estamos usando NHibernate para administrar nuestra persistencia en una aplicación compleja de formularios modulares de Windows, pero un pensamiento me sigue molestando. Actualmente, abrimos una sesión en el lanzamiento y abrimos todos los objetos a través de esa sesión. Me preocupa que todos los objetos cargados se carguen en la memoria caché de la sesión NHibernate, por lo que no pueden ser recogidos basura, y finalmente terminaremos con toda la base de datos en la memoria.¿Cómo administrar las sesiones de NHibernate en una aplicación de formularios de Windows de larga vida?

Esto nunca ocurre con las aplicaciones web porque las solicitudes de páginas web (y aún mejores solicitudes de Ajax) representan la transacción de corta duración perfecta por lo que se puede abrir y cerrar una sesión para manejar cada solicitud.

Sin embargo, si cargo un árbol de objetos en mi aplicación de formularios y los coloco en un panel de navegación en la pantalla, pueden permanecer así durante toda la vida útil de la aplicación, y en cualquier momento el usuario puede hacer clic en ellos. nuestro código necesita navegar las relaciones de objeto a otros objetos (que solo funciona dentro de una sesión de NHibernate).

¿Qué hacen los lectores de StackOverflow para mantener los beneficios de NHibernate sin los problemas que describo?

Respuesta

1

puedo ver un par de alternativas:

  1. Eager-cargar el árbol de objetos (que, por lo que puedo deducir de la documentation es el valor predeterminado)
  2. Separar los objetos, interceptar el "clic "evento, y cargue los datos de la base de datos luego, con una nueva sesión. Éste le obliga a hacerse cargo de las colecciones por sí mismo, en vez de confiar en nhibernate, que puede quedar fuera del alcance de la cuestión (que solicita los beneficios de NHibernate, uno de los cuales es la gestión de cobro)
4

Ayende y compañía generalmente recomiendan usar una sesión por "conversación". Esto generalmente hace que la duración de la sesión dure operaciones muy cortas, por lo que se comporta más como una aplicación web.

Para su caja de árbol, puede usar la solución # 2 de Bruno bien. Los objetos pueden mapearse perezosamente. Luego, cada vez que necesite acceder a una colección de elementos secundarios, iniciará una conversación y volverá a conectar a los padres a través de ISession.Lock. Luego, cuando termine el enlace de datos, cierre esa sesión. No demasiada sobrecarga para mantener, solo unas pocas líneas de código en cualquier forma que necesite llevar una conversación; puede extender el Formulario y los controles que está usando para hacer esto automáticamente si se siente atrevido.

La parte complicada, entonces, son las ediciones simultáneas de diferentes sesiones. ¡No vayamos allí!

+1

Aquí hay un artículo con una buena muestra de cómo implementar la sesión por conversación en una aplicación de escritorio: http://msdn.microsoft.com/en-us/magazine/ee819139.aspx –

3

Abro una sesión cuando la necesito, y la cierro cuando sé que ya no la necesitaré.

Más específicamente, por ejemplo, si tengo un formulario que me permite editar la información del Cliente, por ejemplo, abriré una sesión cuando se genere una instancia del formulario, y cerraré la sesión cuando se cierre el formulario. Cuando tengo 2 instancias de ese formulario abiertas, también tengo 2 sesiones abiertas.

Cuestiones relacionadas