如何从项目列表中批量获取子属性

本文关键字:获取 属性 项目 列表 | 更新日期: 2023-09-27 18:29:05

我有一个搜索方法,它返回多个项,每个项都有几个引用其他表的子属性。对于作为集合的子属性,一切都按照我的意愿进行,但我如何才能对一对一的子属性进行同样的操作?

以下是一些存根和我尝试过的一些代码:

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映射级别指定它。无法在查询级别定义批次大小。

在Fluent 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();