2012-03-27 83 views
1

我有一個搜索方法,它返回多個項目,每個項目都帶有幾個引用其他表的子屬性。 對於作爲集合的兒童財產,一切都按照我想要的方式工作,但我怎樣才能爲一對一的孩子做同樣的事情?如何批量從項目列表中獲取子項目?

下面是一些存根和一些代碼的我嘗試:

public class Request { 
    //HasMany(x => x.Examinations).Access.CamelCaseField().Cascade.All().BatchSize(100); 
    public virtual IList<Examination> Examinations; 

    //References(x => x.Creator, "rem_creator_userid"); 
    public virtual User Creator { get; private set; } 
} 

public class RepositoryExample { 

    // This search will ask one nice-looking query to the database fetchning all the 
    // requests 
    // Then it will ask ONE query fetching the Examinations from the database 
    // Then it will ask N+1 questions fetching Creator from all Requests 
    public IList<Request> Search1(ListRequestSearchConditions searchConditions) { 
     var query = 
      from request in Session.Query<Request>() 
      from exam in request.Examinations 
      where 
       searchConditions.Units.Contains(request.ReferralSource) && 
       exam.Status.HasValue && 
       exam.Status.Value >= ExaminationStatus.Value.RequestSubmitted && 
       request.PatientId != null 
      select request; 

     return query 
      .Skip((searchConditions.Page - 1) * searchConditions.PageSize) 
      .Take(searchConditions.PageSize) 
      .ToList(); 
    } 

    // This search with ask one slow join-query fetching everything from the database 
    public IList<Request> Search2(ListRequestSearchConditions searchConditions) { 
      Examination examinationAlias = null; 

     return Session.QueryOver<Request>() 
      .WhereRestrictionOn(request => request.ReferralSource).IsIn(searchConditions.Units) 
      .Where(request => request.PatientId != null) 
      .JoinAlias(request => request.Examinations,() => examinationAlias) 
      .Where(() => examinationAlias.Status.Value != null) 
      .Where(() => examinationAlias.Status.Value >= ExaminationStatus.Value.RequestSubmitted) 
      .Skip((searchConditions.Page - 1) * searchConditions.PageSize) 
      .Take(searchConditions.PageSize) 
      .ToList(); 
    } 

    // This search will first ask ONE query joining Request with Examinations 
    // Then it will ask ONE query fetching the Examinations from the database 
    // Then it will ask N+1 queries fetching Creator from all Requests 
    public IList<Request> Search3(ListRequestSearchConditions searchConditions) { 
      Examination examinationAlias = null; 

     return Session.QueryOver<Request>() 
      .WhereRestrictionOn(request => request.ReferralSource).IsIn(searchConditions.Units) 
      .Where(request => request.PatientId != null) 
      .JoinAlias(request => request.Examinations,() => examinationAlias) 
      .Where(() => examinationAlias.Status.Value != null) 
      .Where(() => examinationAlias.Status.Value >= ExaminationStatus.Value.RequestSubmitted) 
      .Fetch(request => request.Examinations).Lazy 
      .Fetch(request => examinationAlias.ExaminationType).Lazy; 
      .Skip((searchConditions.Page - 1) * searchConditions.PageSize) 
      .Take(searchConditions.PageSize) 
      .ToList(); 
    } 
} 

我希望能夠做到這一點的3個查詢,一個讀取請求的列表,一個獲取考試和一個取的創作者。

回答

1

如果您不希望在單個查詢中使用它(在LINQ中使用Fetch/ThenFetch)並使用批處理,則必須在Creator映射級別指定它。批量大小無法在查詢級別定義。

在流利的NHibernate中,您可以在Creator映射中添加BatchSize(100)

+0

BATCHSIZE()不適用於一個一對一的映射,其創建者是如此。 – 2012-03-27 18:57:07

+1

將其添加到創建者實體級別上,而不是關係級別上。 – NOtherDev 2012-03-28 09:54:51

+0

非常感謝,不知道你可以在實體級別設置批量大小! – 2012-03-28 10:25:38

0

盡在其中,如果沒有一招地方我不能使用往返

// determine the requests 
var subquery = QueryOver.Of<Request>() 
    .WhereRestrictionOn(request => request.ReferralSource).IsIn(searchConditions.Units) 
    .Where(request => request.PatientId != null) 
    .JoinQueryOver(request => request.Examinations) 
    .Where(examination => examination.Status.Value != null) 
    .Where(examination => examinationAlias.Status.Value >= ExaminationStatus.Value.RequestSubmitted) 
    .Skip((searchConditions.Page - 1) * searchConditions.PageSize) 
    .Take(searchConditions.PageSize) 
    .Select(r => r.Id); 

// load the requests with eagerly fetching the associations 
var results = Session.QueryOver<Request>() 
    .WithSubquery.WhereProperty(request => request.Id).In(subquery) 
    .Fetch(request => request.Creator).Eager 
    .Fetch(request => request.Examinations).Eager 
    .ToList();