Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NHibernate会话管理和延迟加载_C#_Nhibernate_Session_Lazy Loading_Interceptor - Fatal编程技术网

C# NHibernate会话管理和延迟加载

C# NHibernate会话管理和延迟加载,c#,nhibernate,session,lazy-loading,interceptor,C#,Nhibernate,Session,Lazy Loading,Interceptor,我花了很长时间试图找出我在NHibernate的会话管理难题。我认为我的很多麻烦都是由于缺乏对国际奥委会和AOP概念的了解;至少在法比奥·莫洛一直指导我的地方,我是这么想的 无论如何,我的问题是我有一个WinForms应用程序,它正在进行“get”调用并将结果绑定到网格。绑定后,用户可能会执行某种类型的“写入”操作,这些操作会导致会话在写入后关闭,以尝试使用每次使用会话的概念。然后用户可以滚动网格,这会导致延迟加载启动,现在会话已经关闭,我得到一个异常 我不想让我的视图识别我的会话,我不想在用户

我花了很长时间试图找出我在NHibernate的会话管理难题。我认为我的很多麻烦都是由于缺乏对国际奥委会和AOP概念的了解;至少在法比奥·莫洛一直指导我的地方,我是这么想的

无论如何,我的问题是我有一个WinForms应用程序,它正在进行“get”调用并将结果绑定到网格。绑定后,用户可能会执行某种类型的“写入”操作,这些操作会导致会话在写入后关闭,以尝试使用每次使用会话的概念。然后用户可以滚动网格,这会导致延迟加载启动,现在会话已经关闭,我得到一个异常

我不想让我的视图识别我的会话,我不想在用户关闭表单时发送KillAllSessions。此外,用户可能在任何给定时间打开多个表单,这进一步加剧了与该方法相关的问题。我基本上希望所有这些在“幕后”起作用

因此,到目前为止,我的想法是拦截延迟加载调用,检查会话是否打开,如果没有重新打开它,则获取信息,然后重新关闭它。然而,据我所知,这并不多,这基本上就是惰性加载的工作原理。它被代理工厂(NHibernate.Bytecode.Castle)截获,然后使用会话检索数据。因此,我需要实际截获该调用,然后在重新打开会话后将其传递给最初的预期截获。这就是我的想法


我的问题是,首先,这是正确的方法吗?第二,如果是,我甚至不知道从哪里开始。我从未拦截过任何方法调用,我在理论上知道,但在实践中却不知道。我知道有些库可以做这类事情,比如Rhino Commons,但我想借此机会学习并成为一名更好的程序员。我试图理解AOP和上下文绑定的对象,但目前我并没有去探索它。你们中的一些人能帮个忙吗?

我可以想出几个选择:

选项1:在用户与数据交互时保持原始ISession打开,并在用户完成后立即提交所有更改。这意味着您的内存中可能有大量未提交的更改,其他用户将看不到挂起的更改

选项2:将操作拆分为两个工作单元(UOW)。UOW1只读取并负责填充列表。与UOW1关联的ISession保持活动状态,以允许延迟加载,例如在向下钻取场景中。UOW2是为用户编辑而创建的一个新的短期ISession。当编辑提交时,原始对象将从UOW1中退出,UOW1将从数据库中获取新副本


选项3:在每次编辑提交后重新创建列表。这是最简单的解决方案,可能适用于小型数据集。

我正在开发一个类似的应用程序。我正在使用一个我保持开放的会话

每当我写入数据库时,我使用begin/commit事务,它不会关闭底层会话。数据库连接仅在事务进行时由NHibernate打开

当用户正在积极使用表单时,是否有需要关闭会话的原因


您能否提供更多关于您正在使用什么来管理会话、存储库模式等的详细信息。。。等等?

听起来很奇怪。会话应在关闭后释放。你能举个例子吗?对不起,哪一部分看起来很奇怪?就一个例子而言,我只知道告诉你们让我面对这个问题的一系列事件:1。公开会议2。以IList 3的形式获取数据。填写IT类型的自定义集合4。绑定到datagrid 5。任意更改6。此更改要求进行会话7。会话管理器将已打开的会话8交给它。因为它是一个写函数,所以在9完成时关闭会话。用户开始滚动网格,导致延迟加载发生10。由于会话不再打开而引发异常为什么在滚动期间会发生延迟加载?在不知道datagrid背后的代码的情况下,我假设它可能不会填充该列,直到该列出现在用户可见区域中为止。它不一定是一个网格来引起这个问题。如果我做一个单元测试,在其中检索一个对象,我写入另一个对象,然后尝试检索原始对象的延迟加载属性,我将收到相同的异常。@josh-我得到了完全相同的场景,但还没有找到一个好的解决方案。你找到一个你满意的方法了吗?詹姆斯,谢谢你的回答,不过我有个问题。对于选项1和2,如果视图不向会话管理器发送Kill消息告知用户正在关闭应用程序或表单,我如何在“获取”之后关闭会话?我对您的体系结构了解不够,无法发表评论。但是,听起来工作单元边界应该是在窗体关闭时。我认为在本地管理会话生存期比使用一个全局会话管理器更好,全局会话管理器的职责不仅仅是创建新会话。我使用了选项2的一个变体—保持UOW1会话打开,以允许网格在用户浏览时延迟加载。但是管理单个会话进行编辑等工作非常困难。我真的很喜欢Josh的想法,即在访问数据时动态创建一个会话来为惰性负载提供服务。因为我试图阻止我的视图了解我的DAL或其任何工作方式。在我遇到这个问题之前,我的会话是由单例模式管理的。我通过StructureMap创建会话/存储库,只有模型使用它们。我的观点不知道持久性。请注意