[英]Combine workings of Query / QueryOver and DetachedCriteria in NHibernate
在我当前的项目中,我开始使用NHibernate,并且基本上一切运行良好,直到需要将某个实体的完整对象树发送给我的服务使用者为止-急切地从服务器加载和发送的所有内容。
我希望我的查询尽快。
搜索条件非常简单:指定产品和指定部门的完整最新结果对象。
如果我这样调用查询,我将得到正确的结果:(但是这会产生3个查询,至少,我得到了正确的结果)
Result res = session.QueryOver<Result>()
.Where(x => x.Product == product)
.Where(x => x.Department == department)
.OrderBy(x => x.Date).Desc
.Take(1).SingleOrDefault();
但是,并非所有子集合都急切地加载这样的结果。 (是的,它仍然会创建3个查询)。
因为我绝对需要在Content
填充所有ResultContent
类型的项目。 ResultContent
有一些元素的集合,也有它们的集合。 我迫切需要所有这些集合完全填充所有子元素及其子元素的子元素,依此类推。
我现在几乎整天都在处理NHibernate查询,并且几乎可以通过以下查询实现正确的行为:
var resultCriteria = DetachedCriteria.For<Result>();
resultCriteria.SetFetchMode("Product", FetchMode.Eager);
resultCriteria.SetFetchMode("Department", FetchMode.Eager);
resultCriteria.SetFetchMode("Content", FetchMode.Join);
resultCriteria.SetFetchMode("Source", FetchMode.Join);
resultCriteria.SetFetchMode("Content.Numerics", FetchMode.Eager);
resultCriteria.SetFetchMode("Content.Numerics.DataCollection", FetchMode.Join);
resultCriteria.SetFetchMode("Content.Numerics.DataDescription", FetchMode.Join);
resultCriteria.SetFetchMode("Content.Numerics.DataDescription.DescriptionSource", FetchMode.Eager);
resultCriteria.SetMaxResults(5);
var relevantResults = resultCriteria.GetExecutableCriteria(session).List<Result>();
通过这种方法,我得到了5个结果,但是Content集合的填充没有超出第一个元素。 对于以数字表示的DataCollection,仅查询了5个元素,即使应该拉近500个项目也是如此。
我在FetchModes上玩了很多游戏,并且开始认为我将无法实现我将来所需要的东西。 您能否向我暗示正确的方向,我如何才能正确组合这两种方法?
我是否应该使用HQL(我从未使用过,所以我想我会更加努力)?
注意:我在Google上搜索了很多,并尝试了很多东西,但是就NHibernate和sql而言,我认为自己是一个菜鸟。 我将尝试提高自己的技能,但时间压力现在趋向于提出问题。
其他相关的类如下所示(这样您就可以看到哪个类拥有什么的集合,当然也进行了很多简化)
public class Result
{
public virtual long Id { get; protected set; }
public virtual Product Product { get; set; }
public virtual Department Department { get; set; }
public virtual DateTime Date { get; set; }
public virtual ISet<ResultContent> Content { // getters and setters }
public virtual ISet<ResultSource> Source { // getters and setters }
}
public class Product
{
public virtual short Id { get; protected set; }
public virtual string Name { get; set; }
public virtual string Code { get; set; }
public virtual string Description { get; set; }
}
public class Department
{
public virtual short Id { get; protected set; }
public virtual string Name { get; set; }
public virtual string Code { get; set; }
public virtual string Description { get; set; }
}
public class ResultContent
{
public virtual Result Result { get; set; }
public virtual Numerics Numerics { get; set; }
public virtual long Revision { get; set; }
}
public class Numerics
{
public virtual long Id { get; protected set; }
public virtual string Name { get; set; }
public virtual ISet<DataEntry> DataCollection { //getters and setters }
public virtual ISet<DataDescription> DataDescription { //getters and setters}
}
DataEntry和DataDescription类仅包含Id,Date和字符串或布尔值。
嗨,你能尝试一下吗,
Result ra = null;
Product pa = null;
Department da = null;
Result res = session.QueryOver<Result>(() => ra)
.JoinAlias(() => ra.Product ,() => pa)
.JoinAlias(() => ra.Department ,() => da)
.Where(() => pa == product)
.Where(() => da == department)
.OrderBy(() => ra.Date).Desc
.Take(1).SingleOrDefault();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.