2011-05-13 102 views
0

使用Active Record/NHibernate,我試圖選擇具有多個子集合的實體(站點)。選擇具有多個子實體的實體

只有一個站點具有給定的siteId,但FindAll返回站點28次;它正在複製,因爲它正在加載的子集合。我如何獲得它只加載1個站點和子集合的數組?我不介意它是否有5個選擇,其中一個可以抓取該網站,然後每個兒童收集1個。

下面是代碼:

var criteria = DetachedCriteria.For<Site>() 
        .CreateAlias("TimeZone", "tz", NHibernate.SqlCommand.JoinType.InnerJoin) 
        .CreateAlias("Logos", "l", NHibernate.SqlCommand.JoinType.LeftOuterJoin) 
        .CreateAlias("SiteColors", "sc", NHibernate.SqlCommand.JoinType.LeftOuterJoin) 
        .CreateAlias("ManagerUsers", "mu", NHibernate.SqlCommand.JoinType.LeftOuterJoin) 
        .Add(Restrictions.Eq("Id", siteId)); 
       var sites = FindAll(criteria); 

我要指出,我還用獲取嘗試過的HQL方法,但取不取!它只返回一個Site(好),但沒有任何一個孩子集合被急切加載(壞)。

public static Site Get(int id) 
     { 
      var query = new SimpleQuery<Site>(@" 
       from Site s 
       where s.Id = ? 
       inner join fetch s.TimeZone tc 
       left join fetch s.Logos l 
       left join fetch s.SiteColors sc 
       left join fetch s.ManagerUsers mu 
      ", id); 
      var results = query.Execute().ToList(); 
      return results.FirstOrDefault(); 
     } 

這裏是代碼,似乎工作,用「未來」的方法:

public static Site Get(int id) 
     { 
      var session = ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(Site)); 
      var query = session.CreateQuery("from Site s left join fetch s.Logos where s.Id = :id").SetParameter("id", id).Future<Site>(); 
      session.CreateQuery("from Site s left join fetch s.SiteColors where s.Id = :id2").SetParameter("id2", id).Future<Site>(); 
      session.CreateQuery("from Site s left join fetch s.ManagerUsers where s.Id = :id3").SetParameter("id3", id).Future<Site>(); 
      return query.FirstOrDefault(); 
     } 

我所有的數據模型類的從SimpleModel類,我添加的Equals和GetHashCode方法繼承到:

public abstract class SimpleModel 
    { 
     protected SimpleModel() 
     { 
      DateCreated = DateTimeAccess.Now; 
     } 

     [PrimaryKey] 
     [DocumentId] 
     public virtual int Id { get; set; } 

     [Property] 
     public virtual DateTime DateCreated { get; set; } 

     public override bool Equals(object obj) 
     { 
      if (obj is SimpleModel) 
      { 
       return Id.Equals(((SimpleModel)obj).Id); 
      } 
      else 
      { 
       return false; 
      } 
     } 

     public override int GetHashCode() 
     { 
      return Id.GetHashCode(); 
     } 
    } 

回答

1

請致電SetResultTransformer(DistinctRootEntity)在您的條件。它會將這些重複的Site實例摺疊爲單個實例。

欲瞭解更多信息,請參閱本主題:http://groups.google.com/group/nhusers/browse_thread/thread/9919812230702ccc

+0

感謝@Mauricio。使用SetResultTransformer或創建新會話並使用Future方法來加入多個查詢,哪種方法更好? – Justin 2011-05-14 15:14:19

+0

這種方法似乎並不奏效,它迫使那裏只有一個根實體,這很棒,但是它複製了子實體。例如,我的一個子集合應該有21個對象,而現在有31個。 – Justin 2011-05-14 15:23:35

+0

@Justin:確保你已經正確實現了GetHashCode()和Equals() – 2011-05-14 15:31:09