我对FNH和NH世界都很陌生,所以要温柔:P
我已经创建了一个使用FNH进行数据访问的应用程序,它在不使用延迟加载的情况下运行良好,但是一旦我启用了延迟加载,所有内容都会变成梨形(例如,当我尝试访问懒惰时,没有会话打开 - 加载属性等)。
我创建的应用程序布局到目前为止还有一个“数据库”单例,它有各种方法,如Save(),Refer()和List()。
当调用Refer()会话打开时,将检索数据并处理会话;意味着尝试从返回的对象访问延迟加载的属性时没有可用的会话。示例:Database.Refer(“username”)。Person因为延迟加载并且会话已经关闭。
我已经读过Castle有一个SessionManager可以用于这个场景但是,无论是深夜还是缺少咖啡,我似乎无法弄清楚如何连接FNH来使用这个经理,在城堡的精神中,一切都在配置文件中定义。
我错过了什么,还是不能这样做?是否还有其他会话管理员(甚至更合适的会议)?
感谢您对此事的任何帮助。
答案 0 :(得分:0)
我不认为您的特定问题与SessionManager
有关,因为您已经提到过您可以开始新会话并在需要时处理它。
从我对你的帖子的理解是你试图将一个实体暴露给你的视图(带有一些延迟加载的属性) - 这已经是一个坏主意,因为它会导致讨厌的LazyInitializationException(s)
。 / p>
您应该考虑区分data-model
和domain model
。关键概念已在此博客中描述:
Ayende @ Rahien http://ayende.com/blog/4054/nhibernate-query-only-properties
如果您说您正在编写一个非常简单的2层应用程序,那么如果您将在数据层中微观管理您的会话,那么它可能不会有害(但请记住,这不是最好的溶液)。
我还会查看提取实体的查询,因为在我看来,您正在尝试获取只是模型一部分的数据 - 在本例中为Person
。这可能导致严重的问题,如n+1 selects
:
所以一般来说,我认为你应该更多地关注应用程序中结构的方式,而不是搜索SessionManager
,因为它无法解决你的所有问题。
答案 1 :(得分:0)
对于那些仍在寻找答案的人,我将与您分享我迄今所拥有的一切。
这只是我决定使用的框架的一个非常简单的概述,并且到目前为止还不是这个问题的唯一解决方案。
我的代码的基本布局如下:
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);
}
}
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;
}