Nhibernate和Isesence

Nhibernate和Isesence,nhibernate,Nhibernate,假设我有一个简单的视图,显示产品名称以及它是否已经停产。我正在从Northwind数据库中提取数据。我使用了一个简单的模型视图模式和一个带有NHibernate的DAO模式。当表单加载时,我的UI带有一个加载按钮和一个保存按钮。如果我点击了加载按钮,而不是我的代码隐藏,我只需将调用传递给我的演示者来加载数据。preseneter调用DAO来获取数据并用数据填充视图。然后我按了保存按钮。我的代码隐藏再次将呼叫传递给演示者。演示者需要有加载时创建的会话对象来执行乐观并发、更改跟踪等 所以我的问题是,

假设我有一个简单的视图,显示产品名称以及它是否已经停产。我正在从Northwind数据库中提取数据。我使用了一个简单的模型视图模式和一个带有NHibernate的DAO模式。当表单加载时,我的UI带有一个加载按钮和一个保存按钮。如果我点击了加载按钮,而不是我的代码隐藏,我只需将调用传递给我的演示者来加载数据。preseneter调用DAO来获取数据并用数据填充视图。然后我按了保存按钮。我的代码隐藏再次将呼叫传递给演示者。演示者需要有加载时创建的会话对象来执行乐观并发、更改跟踪等


所以我的问题是,我应该在哪里创建ISession对象,以便它可以进行更改跟踪和乐观并发?

HTTP是无状态的。您的工作单元仅存在于服务器端。至于单击“加载”,则UOW只是检索记录并映射到视图模型“保存”和工作单元在您点击服务器时开始,而不是在加载过程中,在浏览器中编辑,然后返回服务器

在实现方面,在ASP.Net会话对象的情况下,您不应该将ISession保留在内存中,它确实是耗尽内存和非托管ado.Net资源的快速方法。有各种各样的UOW示例,有些人选择在begin_请求时将ISession与HTTP上下文关联,并在end_请求时进行dispose。当然,您可以更精细,但在所有情况下,ISession都不存在

在一个简单的系统中,在点击“保存”时,您需要使用ID隐藏字段或其他什么从数据库中拉出产品,从Request.Form中设置属性,然后在数据库中更新

至于并发性。如果在隐藏字段中记录时间戳或增量版本

<input type="hidden" name="version" value="12"/>
然后单击“保存”按钮,将产品从数据库中拉出,检查Request.Form中的版本号是否匹配,然后保存,如果不返回给用户自上次检索以来数据已更改,是否继续?NHibernate有timestamp/version字段,所以当您在更新中实际点击DB时,就会进行比较,基本上是一个where子句,所以在本例中,它甚至会考虑到您提交时的更改


有更详细和复杂的方法,但通常情况下,您不能/不应该在asp.net会话对象中使用ISession。

因为您使用的是MVP,所以我假设这是一个桌面应用程序,而不是web应用程序。UnitOfWork是一个很好的模式。Ayende最近写了一篇关于的优秀文章,所以我肯定会看一看。

不考虑web应用程序。我想知道winform应用程序。很抱歉,我没有在我的问题my bad中指定,在应用程序启动时创建ISession,在完成时关闭。假设您的DB操作没有线程化,这应该可以。如果你敢的话,可以使用单例管理器。虽然我可以证明在应用程序的生命周期中创建一个会话是有效的,但大多数nHibernate“专家”并不建议这样做。我认为存在与缓存相关的内存使用问题,以及在抛出异常或需要回滚事务时可能出现的问题。