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

Nhibernate 使用CreateQuery获取父对象及其子集合,nhibernate,createquery,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 initi

问题是要获取所有孩子的年龄都超过某个年龄的所有家长。预期的输出还应该包括家长的孩子列表

我有以下几点

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());
类父类{
公共虚拟整数Id{get;set;}
公共虚拟IList子项{get;set;}
}
班童{
公共虚拟整数Id{get;set;}
公共虚拟整数{get;set;}
公共虚拟int ParentId{get;set;}
}
//映射
公共类ParentMap:ClassMap
{
公共ParentMap()
{
this.Id(t=>t.Id);
this.HasMany(t=>t.Child).Not.LazyLoad();
}
}
类ParentRepository:IParentRepository{
公共IEnumerable GetAll()
{
使用(var session=\u factory.OpenSession())
{
session.CreateQuery(“从父对象中选择p,c作为p左外部连接p.子对象作为c,其中c.年龄!=:年龄”)
.SetParameter(“年龄”,somevalue);
返回result.Distinct().ToArray();
}
}
}
//在另一个类中,我称为GetAll。
var data=parentRepository.GetAll();
//在下一行,我得到了错误。
IEnumerable parents=Mapper.Map(data.ToArray());
我使用AutoMapper将对象映射到另一个类似的对象(父对象和子对象)。
契约名称空间中的父项和子项具有完全相同类型的属性

NHibernate,其
ISession
确实需要使用不同的方法,然后使用
语句(通常)。我们更喜欢的是有一个
会话
——尽可能晚地打开(例如,甚至一些惰性技术),并尽可能长时间地保持它的打开(如果打开)

对于web应用程序,最常见的方法是(请参阅)

  • 使用BeginRequest/EndRequest打开/关闭会话。使用AOP–属性处理事务。我不确定,但我认为castle的自动交易设施就是这样
  • 使用Asp.Net MVC ActionFilters打开/关闭会话和事务
如果您在web环境中,请检查以下示例:。这段代码的一个片段:

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();
}
即使不是在web请求场景中,也要尝试找到一些方法来处理ISession,并在更多操作中保持它的打开状态。。。检查:


如错误消息所示,您试图在没有打开会话的情况下调用
CreateQuery
。请确保您没有关闭/处理会话,或在调用
CreateQuery
的地方发布代码。