2014-03-12 45 views
0

問題是要獲得所有孩子的年齡都高於某個特定年齡的所有父母。期望的輸出結果還應包括子女列表及其父母。使用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映射該對象到另一個類似的對象(Parent和Child)。 家長並在合同中命名空間中的孩子有完全相同的類型屬性

+0

如錯誤消息所示,您正試圖在沒有打開的會話時調用'CreateQuery'。請確保您沒有關閉/處理會話,或者在您調用'CreateQuery'的地方發佈代碼。 –

回答

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(); 
} 

即使未在Web請求的情況下,試圖找出一些方法如何處理的ISession,並保持在打開更多的操作...檢查:

Building a Desktop To-Do Application with NHibernate