NHibernate查询具有子集合的实体,并对DB进行一次查询

时间:2017-11-21 08:25:51

标签: nhibernate fetch queryover

如何通过向DB发送一个查询sql或者多少sql来使用查询来查询具有子集合的实体? 我有一些课程如下

public class Project
{
    public int ProjectId {get;set;}
    public int ProjectNumber {get;set;}
    public Customer Customer {get;set;}
    public LocalizedText LocalizedText {get;set;}
}
public class Customer
{
    public int CustomerId {get;set;}
    public string Name {get;set;}
}

public class LocalizedText
{
    public int LocalizedTextId { get; set; }
    public List<LocalizedTextValue> LocalizedTextValues { get; set; 
}
}
public class LocalizedTextValue
{
    public LocalizedText LocalizedText { get; set; }
    public int CultureId { get; set; }
    public string Value { get; set; }
}

我想查询有条件的项目,然后我写一个查询,如下所示

    var test = Session.QueryOver<Project>()
                .JoinAlias(x => x.Customer, () => customer)
                .Where(x => customer.Name = "Abc")
                .OrderBy(x => x.ProjectNumber).Asc
                .Fetch(x => x.LocalizedText).Eager
                .Fetch(x => x.LocalizedText.LocalizedTextValues).Eager
                .Future<Project>()
                .Distinct()
                .Select(x => new DTO.ProjectForActualTime
                {
                    ProjectName = x.ProjectNumber + " - " + x.LocalizedText.LocalizedTextValues[0].Value,
                    ProjectId = x.ProjectId,
                    ProjectNumber = x.ProjectNumber
                }).ToList();

但是此查询将根据结果计数向DB发送多个sql命令。此查询将发送带有项目左连接客户,LocalizedText,LocalizedTextValue和许多sql的SQL到LocalizedTextValue表,然后此查询将花费很多秒。 我写了一个Native sql查询,如下所示,它只会向DB发送一个sql,然后它只需要0.2s。

        var projectSql = @"select p.ProjectId, p.ProjectNumber
                            ,convert(nvarchar(20),p.ProjectNumber) + ' - ' + ltv.Value ProjectName        
                            from Project p 
                            left join Customer cs on cs.CustomerId = p.CustomerId
                            left join LocalizedText lt on lt.LocalizedTextId = p.NameLocalizedTextId
                            left join LocalizedTextValue ltv on ltv.LocalizedTextId = lt.LocalizedTextId
                            where cs.Name = :customerName
                            and ltv.CultureId = :cultureId 
                            order by p.ProjectNumber";

           var projects = Session
                .CreateSQLQuery(projectSql)
                .SetParameter("customerName", "Abc")
                .SetParameter("cultureId", cultureId)
              .SetResultTransformer(Transformers.AliasToBean(typeof(ProjectForActualTime)))
                .List<ProjectForActualTime>().ToList();

如何将我的查询更新为与本机sql类似,以便向DB发送较少的sql命令?如果查询向DB发送较少的sql,则查询将花费较少的秒数和几乎本机的SQL查询。

我找到一个让Nhibernate使用本机sql查询生成相同sql的解决方案,我使用selectList和TransformUsing来查询与本机sql相同的DTO结果。 the transform document

    var projects = Session.QueryOver<Project>(() => project)
                .JoinAlias(x => x.Customer, () => customer)
                .JoinAlias(x => customer.Client, () => client)
                .JoinAlias(x => x.ProjectStatus, () => projectStatus)
                .JoinAlias(x => x.LocalizedText, () => localizedText)
                .JoinAlias(x => localizedText.LocalizedTextValues, () => localizedTextValue)
                .Where(x => x.Deleted == null && client.ClientId == loginUser.ClientId
                    && projectStatus.Code != proposalCode
                    && localizedTextValue.Culture.CultureId == cultureId)
                .OrderBy(x => x.ProjectNumber).Asc
                .SelectList(list => list
                .Select(() => project.ProjectId).WithAlias(() => projectForActualTime.ProjectId)
                .Select(() => project.ProjectNumber).WithAlias(() => projectForActualTime.ProjectNumber)
                .Select(() => localizedTextValue.Value).WithAlias(() => projectForActualTime.ProjectNameWithoutNumber)
                .Select(() => project.ManagerUser.UserId).WithAlias(() => projectForActualTime.ProjectMangerUserId)
                .Select(() => projectStatus.ProjectStatusId).WithAlias(() => projectForActualTime.StatusId)
                )
                .TransformUsing(Transformers.AliasToBean<DTO.ProjectForActualTime>())
                .List<DTO.ProjectForActualTime>()
                .ToList();

this is the sql which send to DB projectClassMap LocalizedTextMap LocalizedTexValueMap LocalizedTextClass

0 个答案:

没有答案