Nhibernate在一个SQL查询中进行多对多的即时加载?
如何强制nhibernate在一个sql查询中完全加载多对多数据。 我试过这个:Nhibernate在一个SQL查询中进行多对多的即时加载?,nhibernate,fluent-nhibernate,many-to-many,criteria,eager-loading,Nhibernate,Fluent Nhibernate,Many To Many,Criteria,Eager Loading,如何强制nhibernate在一个sql查询中完全加载多对多数据。 我试过这个: var list = session.CreateCriteria<Q>("q") .CreateAlias("q.PList", "p", JoinType.LeftOuterJoin) .List(); var list=session.CreateCriteria(“q”) .CreateAlias(“q.PList”,“p
var list = session.CreateCriteria<Q>("q")
.CreateAlias("q.PList", "p", JoinType.LeftOuterJoin)
.List();
var list=session.CreateCriteria(“q”)
.CreateAlias(“q.PList”,“p”,JoinType.LeftOuterJoin)
.List();
但它只加载q.PList,当我尝试访问q.PList[0].QList[0].PList[0]时,NH会执行额外的select查询
实体以及我如何映射它们:
public class P
{
public virtual Guid Id { get; set; }
public virtual IList<Q> QList { get; set; }
}
public class Q
{
public virtual Guid Id { get; set; }
public virtual IList<P> PList{ get; set; }
}
public class PMap : ClassMap<P>
{
public PMap()
{
Table("p");
Id(t => t.Id);
HasManyToMany(t => t.QList)
.Table("q2p").ParentKeyColumn("pId").ChildKeyColumn("qId").Inverse();
}
}
public class QMap : ClassMap<Q>
{
public QMap()
{
Table("q");
Id(t => t.Id);
HasManyToMany(t => t.PList)
.Table("q2p").ParentKeyColumn("qId").ChildKeyColumn("pId");
}
}
公共类P
{
公共虚拟Guid Id{get;set;}
公共虚拟IList QList{get;set;}
}
公共类Q
{
公共虚拟Guid Id{get;set;}
公共虚拟IListPList{get;set;}
}
公共类PMap:ClassMap
{
公共PMap()
{
表(“p”);
Id(t=>t.Id);
HasManyToMany(t=>t.QList)
.Table(“q2p”).ParentKeyColumn(“pId”).ChildKeyColumn(“qId”).Inverse();
}
}
公共类QMap:ClassMap
{
公共QMap()
{
表(“q”);
Id(t=>t.Id);
HasManyToMany(t=>t.PList)
.Table(“q2p”).ParentKeyColumn(“qId”).ChildKeyColumn(“pId”);
}
}
我相信您真正想做的是:
var list = session.CreateCriteria<Q>()
.SetFetchMode("PList", FetchMode.Join)
.List();
var list=session.CreateCriteria()
.SetFetchMode(“PList”,FetchMode.Join)
.List();
根据您的评论更新:
这很麻烦,而且通常不值得尝试使用联接获取包含多个集合的整个图。对于这种特殊情况,我建议您对集合使用batch size
,并让NH执行批处理延迟加载
根据您的代码,HQL查询也可能比导航对象图更好地检索您想要的数据。或者使用HQL来实现相同的功能 您的查询如下所示
var hqlQuery="select p from Q as q inner join fetch q.PList as p";
您可以按如下方式运行查询:
Sesssion.CreateQuery(hqlQuery).List<P>();
sessession.CreateQuery(hqlQuery).List();
希望能有所帮助。这将生成与我的代码相同的SQL和结果。我需要立即加载它,并摆脱延迟加载。fluent生成的xml映射是什么?我刚刚尝试了它(使用NH3和几乎默认的符合映射),它正确地生成了两个联接。啊,实际上,当我尝试访问q.PList[0].QList[0].PList[0而不是q.PList[0].QList[0]生成的映射时:我通过添加.not.LazyLoad().FetchType.Join()使它能够快速加载,这会导致“指定fetch=”的另一个结果subselect“有影响力,现在数据已经在两个查询中完全加载,为什么不加入工作对我来说仍然是个谜。