nhibernate - una - orden de tabulacion visual basic
¿Cómo administrar las sesiones de NHibernate en una aplicación de formularios de Windows de larga vida? (4)
Estamos utilizando 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.
Esto nunca sucede 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í mientras dure la aplicación, y en cualquier momento el usuario puede hacer clic en ellos, lo que hace que nuestro código necesite navegue por 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?
Puedo ver un par de alternativas:
- Eager-load el árbol de objetos (que, por lo que puedo recoger de la documentación es el predeterminado)
- Separe los objetos, intercepte el evento "clic" y cargue los datos de la base de datos con una nueva sesión. Esto lo obliga a cuidar de las colecciones usted mismo, en lugar de confiar en el nhibernate, que puede quedar fuera del alcance de la pregunta (que solicita los beneficios de NHibernate, uno de los cuales es la gestión de la recolección).
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 el formulario sea instanciado, y cerraré la sesión cuando el formulario se cierre. Cuando tengo 2 instancias de ese formulario abiertas, también tengo 2 sesiones abiertas.
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 sin problemas. 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; Puedes extender el Formulario y los controles que estás usando para hacer esto automáticamente si te sientes descarado.
La parte difícil, entonces, son las ediciones simultáneas de diferentes sesiones. ¡No vayamos allí!
Puedes echar un vistazo a mis publicaciones sobre cómo usar uNHAddins para trabajar con sesión por conversación en una aplicación de Windows Forms (uNHAddins es un proyecto con algunas adiciones a NHibernate liderado por Fabio Maulo, actual NH Lead)
La primera publicación es esta
http://gustavoringel.blogspot.com/2009/02/unhaddins-persistence-conversation-part.html
Desde allí, tiene enlaces al tronco de uNHAddins.