关于第一个问题。如果您只是要读取实体,则无需执行任何操作。即使将其作为字段分配给不同的实体也不需要您锁定记录。您需要调用的唯一原因ISession.Lock
是当您想要变异然后保存实体时。
有一个例外,那就是延迟加载。如果实体具有在第一个会话处于活动状态时未加载的外部子记录,则稍后尝试访问它们时将引发异常。最简单的解决方法是在第一个会话中触摸子集合。
如果实体在这些情况下仍然给您带来问题,您可以添加一个Load
到您的存储库。您可以将其连接到ISession.Load
. 所做的是在Load
不访问数据库的情况下为实体创建一个空代理。该实体是加载该实体的会话的一部分,可用于分配给其他实体的属性。这种方法的优点是它更干净,并且很容易通过单元测试来模拟。
关于第二个问题。是的,你是对的,它闻起来集成ISession.Lock
到存储库中。同样,当您不必改变实体时,您不必担心这一点。但是,当您这样做时,您真的应该考虑从存储库中重新加载实体并处理该实体。我知道它不是最理想的,但它为您节省了很多非常奇怪的代码,特别是在您的单元测试中。
最后一件事。我知道您正在谈论一个将存在很长时间的实体(可能是应用程序的完整运行时)。您的生命周期大致分为三类:1. 永远、2. 长和 3. 短。我提到这一点的原因不止一次,具有“长”生命周期的实体的问题实际上可能只是与具有相同生命周期的会话保持连接。让会话活动 5 或 10 分钟(用户在表单中输入数据的时间)不是问题。仅此一项就可以为大多数人省去很多麻烦。
另一个注意事项:看看NHibernateUtil
and NHibernateProxyHelper
。这些类可以帮助您强制加载实体和子集合。