如何批量从项目列表中获取子项目?
问题描述:
我有一个搜索方法,它返回多个项目,每个项目都带有几个引用其他表的子属性。 对于作为集合的儿童财产,一切都按照我想要的方式工作,但我怎样才能为一对一的孩子做同样的事情?如何批量从项目列表中获取子项目?
下面是一些存根和一些代码的我尝试:
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个查询,一个读取请求的列表,一个获取考试和一个取的创作者。
答
如果您不希望在单个查询中使用它(在LINQ中使用Fetch
/ThenFetch
)并使用批处理,则必须在Creator
映射级别指定它。批量大小无法在查询级别定义。
在流利的NHibernate中,您可以在Creator
映射中添加BatchSize(100)
。
答
尽在其中,如果没有一招地方我不能使用往返
// 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();
BATCHSIZE()不适用于一个一对一的映射,其创建者是如此。 – 2012-03-27 18:57:07
将其添加到创建者实体级别上,而不是关系级别上。 – NOtherDev 2012-03-28 09:54:51
非常感谢,不知道你可以在实体级别设置批量大小! – 2012-03-28 10:25:38