我的代码如下。我的问题是当我使用NHibernate检索包含导航属性的对象并尝试在该导航属性对象中设置一个值时,它会抛出一个错误,说明该会话不存在。
[' f.HIERARCHY.CHANGETIME = DateTime.Now;'主要方法内的行]
我知道这是因为当NHibernate试图获取' HIERARCHY'对象会话已在存储库类
中关闭我需要知道的是编写代码的标准方法,以便我仍然可以使用延迟加载,但可以在代码中稍后访问导航对象的属性,而不会禁用延迟加载。
始终保持Isession对象的开放是一种好方法吗?我在互联网上找到的大多数代码样本总是在每个操作的每个CRUD操作中打开一个新会话,并在之后立即关闭它。它们如何解决代码中稍后访问导航属性的问题?
public class NHibernateBaseRepository : IDisposable
{
private ISessionFactory m_SessionFactory = null;
private ISession m_Session = null;
public T GetById<T>(long id)
{
using (ISession session = m_SessionFactory.OpenSession())
{
return session.Get<T>(id);
}
}
}
public class ROLE
{
public virtual string RoleComment { get; set; }
public virtual HIERARCHY HIERARCHY { get; set; }
}
public class HIERARCHY_STRUCTURE
{
public virtual DateTime CHANGETIME{ get; set; }
}
class Program
{
static void Main(string[] args)
{
NHibernateBaseRepository persistenceManager = new NHibernateBaseRepository();
ROLE f = persistenceManager.GetById<ROLE>(34);
f.RoleComment = "Test Com";
f.HIERARCHY.CHANGETIME = DateTime.Now; //Throws error
persistenceManager.SaveOrUpdateEntitiy<ROLE>(f);
}
}
&#13;
答案 0 :(得分:0)
他们如何解决代码中稍后访问导航属性的问题?
没有禁用延迟加载
尝试在会话打开时在存储库中使用Fetch()方法。例如:
private IList<Container> ReadContainer()
{
var modeList = new List<Container>();
using (var session = DatabaseHelper.OpenSession())
{
var tmp = session.Query<Container>().Fetch(items => items.TmcList).ToList();
}
return modeList;
}
答案 1 :(得分:0)
您需要做的主要是更改管理Session对象生命周期的方式,并将其与单个存储库方法调用隔离开来,这将为您提供写入和查询批处理等优势。
这意味着,您必须以更全局的方式定义Session,可能作为NHibernateBaseRepository类中的私有字段,在构造函数中实例化它,然后实现IDisposable,并在Dispose方法中关闭会话。这样,您可以在同一会话中执行多个操作(以及更一致的工作单元)。
一些代码示例:
NHibernateBaseRepository类:
public class NHibernateBaseRepository : IDisposable
{
private ISession _session;
public NHibernateBaseRepository ()
{
_session = m_SessionFactory.OpenSession(); //session factory should be created once per application lifetime, not per instance.
}
public void Dispose()
{
_session.Dispose();
}
public T GetById<T>(long id)
{
return _session.Get<T>(id);
}
}
主要方法:
static void Main(string[] args)
{
using(var persistenceManager = new NHibernateBaseRepository())
{
ROLE f = persistenceManager.GetById<ROLE>(34);
f.RoleComment = "Test Com";
f.HIERARCHY.CHANGETIME = DateTime.Now; //Throws error
persistenceManager.SaveOrUpdateEntitiy<ROLE>(f);
}
}