Fluent NHibernate ISessionManager或同等级别
本文关键字:NHibernate ISessionManager Fluent | 更新日期: 2023-09-27 18:00:53
我对FNH和NH世界很陌生,所以要温和:p
我已经创建了一个使用FNH进行数据访问的应用程序,它在不使用延迟加载的情况下运行良好,但一旦我启用了延迟加载,一切都会变成梨形(如中所示,当我尝试访问延迟加载的属性时,没有会话打开等(。
到目前为止,我创建的应用程序布局有一个"Database"单例,它有各种方法,如Save((、Refer((和List((
当调用Refer((时,打开一个会话,检索数据并处理该会话;这意味着当试图从返回的对象访问延迟加载的属性时,没有可用的会话。示例:数据库。请参阅("用户名"(。Person,因为Person是惰性加载的,并且会话已经关闭。
我读到Castle有一个SessionManager,可以用于这种情况,但无论是深夜还是缺少咖啡,我似乎都不知道如何连接FNH来使用这个管理器,因为本着Castle的精神,一切都在配置文件中定义。
我是错过了什么,还是不能这样做?我是否应该考虑其他会话管理器(甚至更合适的约定(?
谢谢你在这件事上的帮助。
我不认为您的特定问题与SessionManager
有关,因为您已经提到您能够启动新会话并在需要时处理它。
根据我对你的帖子的理解,你试图将一个实体暴露在你的视图中(带有一些懒惰加载的属性(——这已经是一个坏主意,因为它会导致令人讨厌的LazyInitializationException(s)
。
您应该考虑区分您的data-model
和domain model
。这个博客描述了关键概念:
Ayende@Raheenhttp://ayende.com/blog/4054/nhibernate-query-only-properties
如果您说您正在编写一个非常简单的2层应用程序,那么如果您在数据层中对会话进行微观管理(,但请记住,这不是最好的解决方案(,可能不会有什么害处。
我还将研究获取实体的查询,因为在我看来,您试图获取的数据只是模型的一部分——在本例中为Person
。这可能会导致严重的问题,如n+1 selects
:
什么是SELECT N+1?
因此,总的来说,我认为您应该更多地关注应用程序中事物的结构,而不是搜索SessionManager
,因为它不会解决所有问题。
对于任何仍在寻找答案的人,我将与您分享我迄今为止所拥有的。
这只是我决定使用的框架的一个非常简单的概述,并不是这个问题的唯一解决方案。
我的代码的基本布局如下:
- NHibernate存储库(参考我的模型部件和UoW部件(
- 基于HibernatingRhino的Repository实现进行了修改,以满足我的需求。在此处找到:http://ayende.com/Wiki/Rhino+Commons.ashx
public T Get(Guid Id) { return WrapUOW(() => { using (Audit.LockAudit()) return (T)Session.Get(typeof(T), Id); }); } public void LoadFullObject(T partial) { if (partial == null) throw new ArgumentNullException("partial"); if (partial.Id == Guid.Empty) return; WrapUOW(() => { using (Audit.LockAudit()) { LazyInitialiser.InitialiseCompletely(partial, Session); } }); } public T SaveOrUpdate(T entity) { using (Audit.LockAudit()) { With.Transaction(() => { Enlist(entity); Session.SaveOrUpdate(entity); entity.HasChanged = false; }); } return entity; } protected void Enlist(T instance) { if (instance != null && instance.Id != Guid.Empty && !Session.Contains(instance)) using (Audit.LockAudit()) { Session.Update(instance); } }
- References a neat little helper class called 'Lazy Initializer for NHibernate' found here: http://www.codeproject.com/KB/cs/NHibernateLazyInitializer.aspx
- This also contains Extension methods for Save, Delete and LoadFullObject
-
Have broken standards a little in this assembly by also creating a WrapUOW method to help simplify some of my code
protected static T WrapUOW(Func action) { IUnitOfWork uow = null; if (!UnitOfWork.IsStarted) uow = UnitOfWork.Start(); T result = action(); if (uow != null) uow.Dispose(); return result; }
- 基于HibernatingRhino的Repository实现进行了修改,以满足我的需求。在此处找到:http://ayende.com/Wiki/Rhino+Commons.ashx
- NHibernate工作单元(参考我的模型部件(
- 同样基于HibernatingRhino的UoW实现,并进行了修改以适应
- 视图-不重要,只是MVVM实现所需
- 绑定ViewModel中的值
- 型号
- 包含我的实体类和hibernate映射文件
- ViewModel
- 包含两个主要视图基类,ListPage和MaintenancePage
- ListPage基类只是根据我们列出的对象类型调用RepositoryList方法。这将加载实体的脱水列表
- MaintenancePage从ListPage获取一个实体实例并调用Repository。LoadFullObject方法来重新水合实体以在屏幕上使用。
- 这允许在屏幕上使用绑定
- 我们也可以安全地调用存储库。此页面中的SaveOrUpdate方法