使用CreateQuery获取父对象及其子集合

时间:2014-03-12 20:29:42

标签: nhibernate createquery

问题是要让所有孩子年龄超过一定年龄的所有父母。预期的输出还应包括与其父母一起的儿童名单。

我有以下......

session.CreateQuery("select p, c from Parent as p left outer join p.Children as c where c.Age!= :age")
 .SetParameter("age", somevalue);

但是我收到以下错误:

Initializing[ns.Parent #18]-failed to lazily initialize a collection
of role: ns.Children, no session or session was closed

这是我的代码:

class Parent {
   public virtual int Id { get; set; }
   public virtual IList<Child> Children { get; set; }
}


class Child {
   public virtual int Id { get; set; }
   public virtual int Age{ get; set; }
   public virtual int ParentId { get; set; }   
}

  //the mapping

  public class ParentMap : ClassMap<Parent>
    {
        public ParentMap()
        {
            this.Id(t => t.Id);         
            this.HasMany(t => t.Child).Not.LazyLoad();
        }
    }

    class ParentRepository : IParentRepository {

        public IEnumerable<Parent> GetAll()
        {

                using (var session = _factory.OpenSession())
                {
                    session.CreateQuery("select p, c from Parent as p left outer join       p.Children as c where c.Age!= :age")
                    .SetParameter("age", somevalue);

                    return result.Distinct().ToArray();
                }

        }
    }

//In a different class I call GetAll.
var data = parentRepository.GetAll();
//at the following line that i get the error. 
    IEnumerable<Contracts.Parent> parents = Mapper.Map<IEnumerable<ns.Parent>,        IEnumerable<Contracts.Parent>>(data.ToArray());

我使用AutoMapper将对象映射到另一个类似的对象(父对象和子对象)。 Contract名称空间中的Parent和Child具有完全相同的属性类型

1 个答案:

答案 0 :(得分:0)

NHibernate及其ISession确实需要不同的方法,然后using语句(通常)。我们更喜欢的是让session - 尽可能晚地打开(例如甚至是一些懒惰技术)并保持打开(如果打开)越长越好。

对于Web应用程序,最常见的方法是(请参阅Effective NHibernate Session management for web apps

  • 使用BeginRequest / EndRequest打开/关闭会话。使用AOP处理事务 - 属性。我不确定,但我认为这就是城堡的AutoTransaction设施的情况。
  • 使用Asp.Net MVC ActionFilters打开/关闭会话和事务。

如果您在网络环境中,请检查以下示例:session-per-web-global.cs。该代码的片段:

public static ISessionFactory SessionFactory { get; private set; }
protected void Application_Start()
{
    ...     
    //Configure NHibernate and create a session factory for the application
    var nhibernateConiguration = new NHibernate.Cfg.Configuration();
    nhibernateConiguration.Configure();
    SessionFactory = nhibernateConiguration.BuildSessionFactory();
}

protected void Application_BeginRequest(object sender, EventArgs e)
{
    //Create NHibernate session for this request and bind it to the
    //NHibernate session context (configured as web context using HttpContext)
    var session = SessionFactory.OpenSession();
    NHibernate.Context.CurrentSessionContext.Bind(session);
}

protected void Application_EndRequest(object sender, EventArgs e)
{
    //Detach the session from this web request
    var session = NHibernate.Context.CurrentSessionContext.Unbind(SessionFactory);
    session.Dispose();
}

即使不在网络请求场景中,也要尝试找出如何处理ISession的一些方法,并通过更多操作保持开放...检查:

Building a Desktop To-Do Application with NHibernate