使用NHibernate有效地检索具有嵌套集合的对象

使用NHibernate有效地检索具有嵌套集合的对象,nhibernate,Nhibernate,我正在创建一个调查应用程序,其中有一个包含页面集合的调查。每个页面都有一组问题,每个问题都有一组答案选项。我的班级结构如下: public class Survey : Entity { public IList<Page> Pages { get; set; } } public class Page : Entity { public IList<Question> Questions { get;set; } } public class Que

我正在创建一个调查应用程序,其中有一个包含页面集合的调查。每个页面都有一组问题,每个问题都有一组答案选项。我的班级结构如下:

public class Survey : Entity {
    public IList<Page> Pages { get; set; }
}

public class Page : Entity {
    public IList<Question> Questions { get;set; }
}

public class Question : Entity {
    public IList<Option> Options { get; set; }
}

public class Option : Entity {}
我也尝试过将来的查询,但它们无助于减少查询的数量

有什么想法吗?

您可以尝试添加

lazy="false" fetch="join"

到你的包里去。这样,您就可以通过一个查询确保取回行李。

我使用的解决方案是颠倒实体之间的关系。使用此方法,您可以确保在加载
调查
的记录时,除非调用
LoadAll
方法,否则不会加载
页面
的记录。LoadAll是每个类中搜索所有相关记录的方法。考虑下面的代码:

public class Survey : Entity {
Survey[] LoadAll {
string hql = "from Page page where page.SurveyID =" + this.ID;
//....
}
}

public class Page : Entity {
    public Survey { get;set; }
}

public class Question : Entity {
    public Page Page { get; set; }
}

public class Option : Entity {
    public Question Question {set; get;}
}

如果我理解正确,您可以通过以下HQL实现这一点(当然,同样的想法也可以用于iCiteria)

如果您还想获取
survey.Questions
,那么最好的选择是在单独的qyery和二手期货中获取这些问题,以避免笛卡尔积


另外,如果我没记错的话,HQL查询会忽略映射中定义的fetch。如果集合映射为
lazy=“false”fetch=“join”
,则在使用ICriteria时是fetch,但在使用HQL时不是。

我在映射中添加了lazy=“false”,但没有fetch,这没有帮助。添加fetch减少了查询。但是,我不想更改映射,因为我只获取一个问题或测量对象,不需要集合。这可以使用HQL或标准API来完成吗?正确。我有一个LoadAll方法,但在调查类中没有。我想知道的是,是否有一种方法可以编写HQL(或标准)以最有效的方式加载调查、所有页面、每页中的所有问题以及每个问题的所有答案选项。如果我使用SQL,我会在
选项上使用
选择distinct
lazy="false" fetch="join"
public class Survey : Entity {
Survey[] LoadAll {
string hql = "from Page page where page.SurveyID =" + this.ID;
//....
}
}

public class Page : Entity {
    public Survey { get;set; }
}

public class Question : Entity {
    public Page Page { get; set; }
}

public class Option : Entity {
    public Question Question {set; get;}
}
from Survey s
  inner join fetch s.Pages p
  inner join fetch p.Questions q
  inner join fetch q.Options
where s.Id = :id