C# 实体对象和NHibernate会话

C# 实体对象和NHibernate会话,c#,silverlight,nhibernate,entity,C#,Silverlight,Nhibernate,Entity,我们的第一个NHibernate项目进展顺利。但是,我仍然没有完全掌握如何管理场景中的会话和对象 因此,我们在一个持久对象模型中配置一个系统结构,它存储在一个带有NHibernate的数据库中 系统由物理设备组成,应用程序在服务过程中对其进行监控。因此,在服务启动时,我们实例化服务中的设备对象,并根据从设备接口读取的数据更新它们的状态。对象模型在服务生命周期内保持活动状态 该服务还为Silverlight客户机提供服务,这些客户机显示对象数据,还可能操作某些对象。但它们必须访问服务用于监视的相同

我们的第一个NHibernate项目进展顺利。但是,我仍然没有完全掌握如何管理场景中的会话和对象

因此,我们在一个持久对象模型中配置一个系统结构,它存储在一个带有NHibernate的数据库中

系统由物理设备组成,应用程序在服务过程中对其进行监控。因此,在服务启动时,我们实例化服务中的设备对象,并根据从设备接口读取的数据更新它们的状态。对象模型在服务生命周期内保持活动状态

该服务还为Silverlight客户机提供服务,这些客户机显示对象数据,还可能操作某些对象。但它们必须访问服务用于监视的相同对象,例如,因为这些对象也有内存中的数据,而这些数据不会持久化。(是的,我们使用DTO对象将数据实际传输到客户端。)

由于该服务是一个多线程系统,因此问题在于如何管理NHibernate会话

我现在正在考虑一种方法,我们只需要一个后台线程来处理后台的对象持久性,其他线程只需将“SaveRequests”放入我们的存储库,而不是直接访问NHibernate会话。通过这种方式,我可以为服务使用单个会话,并将NHibernate层与访问对象的服务和客户端完全分开管理

我还没有找到任何关于这种设置的文档,因为每个人都建议使用每个请求的会话模型或一些变体。但是如果我做对了,如果我在一个会话中实例化一个对象并在另一个会话中保存它,它就不是同一个对象了——而且似乎NHibernate会在数据库中创建一个新条目

我还试图在这种情况下理解IOC容器的作用,但我没有找到任何有用的例子来证明它们真的可以帮助我


我是否在正确的轨道上,或者我应该如何进行?

将ISession视为一个工作单元。您需要在应用程序的上下文中定义构成工作单元的内容。工作单元是围绕一系列较小操作的边界,这些操作构成一个完整的功能性任务(完整的功能性任务由您在应用程序设计中定义)。是您的服务响应Silverlight客户端请求还是其他外部请求?是在服务醒过来对计时器做一些工作的时候吗?所有这些

您希望为该工作单元创建会话,并在会话完成时进行释放。不建议您使用长时间运行的ISession实例,在这些实例中,操作会懒洋洋地使用它们可以找到的任何环境ISession

这种想法通常被描述为:

  • 我需要做一些工作(因为我正在响应一个事件,不管它是传入的请求,还是计时器上的作业,都无所谓)
  • 因此,我需要开始一个新的工作单元(这有助于我跟踪执行此工作时需要执行的所有操作)
  • 工作单位开始了一个新的任务来跟踪我的工作
  • 我做我的工作
  • 如果我能够成功地完成我的工作,我的所有更改都应该刷新并提交
  • 如果没有,请回滚所有更改
  • 我自己打扫(处理垃圾等)

  • 是的,我已经考虑过了。但是因为我有“永远”的对象,我认为单位工作也应该永远存在。或者,如何将一个会话中的更改与服务会话中始终处于活动状态的对象相关联?主界面不是客户端,而是跟踪系统状态的服务应用程序,对象中也有实时数据(如状态和当前值)。我想不出有哪种情况下,您希望“对象处于活动状态”的时间超过1秒钟……我们决定监控基于跟踪系统当前状态的对象,因为这是主要部分。它们的配置是持久化的,但通常不是当前状态。是的,因此该对象不应该是持久化的一部分,因此不应该是NHibernate会话的一部分。只要系统在它们上积极运行,它们就应该被认为是“活动的”。如果没有,他们就死了,应该被收集起来扔掉。您可以在下次需要时再次重新加载它们。如果您担心性能,请考虑NHiBeNATE支持的2级缓存。此缓存对ISessionFactory创建的所有会话都可见。