如何通过向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