NHibernate方法维护Isession对象

时间:2015-03-09 05:24:10

标签: c# nhibernate

我的代码如下。我的问题是当我使用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;
&#13;
&#13;

2 个答案:

答案 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);
     }
}