我有一个实体,上面有多个其他实体的集合,我想热切地加载它们,理想情况是一批。示例设置如下:
public Entity1
{
public virtual int Prop1 {get;set;}
public virtual string Prop2 {get;set;}
public virtual IList<Entity2> Prop3 {get;set;}
public virtual IList<Entity3> Prop4 {get;set;}
}
public Entity2
{
public virtual int Prop1 {get;set;}
public virtual string Prop2 {get;set;}
}
public Entity3
{
public virtual int Prop1 {get;set;}
public virtual string Prop2 {get;set;}
public virtual IList<Entity1> Prop3 {get;set;}
}
实体映射:
public class Entity1Map : ClassMap<Entity1>
{
public ClientMap()
{
Table("Clients");
Id(m => m.Prop1);
Map(m => m.Prop2);
}
}
public class Entity1Map : ClassMap<Entity1>
{
public Entity1Map()
{
Table("Entity1Table");
Id(m => m.Prop1);
Map(m => m.Prop2);
HasMany(m => m.Prop3).KeyColumn("Prop1").LazyLoad().NotFound.Ignore();
HasMany(m => m.Prop4).KeyColumn("Prop1").LazyLoad().NotFound.Ignore();
}
}
public class Entity2Map : ClassMap<Entity2>
{
public Entity2Map()
{
Table("Entity2Table");
Id(m => m.Prop1);
Map(m => m.Prop2);
}
}
public class Entity3Map : ClassMap<Entity3>
{
public Entity3Map()
{
Table("Entity3Table");
Id(m => m.Prop1);
Map(m => m.Prop2);
HasOne(m => m.Prop3).ForeignKey("Prop1").LazyLoad();
}
}
使用以下方法查询数据库:
var query = session.CreateCriteria<Entity1>()
.CreateCriteria("Prop3", "prop3", JoinType.InnerJoin)
.Add(Restrictions.Eq(Projections.Property("Prop2"), "Criteria!"))
.SetFetchMode("Prop3", FetchMode.Join)
.SetFetchMode("Prop4", FetchMode.Join);
var clients = query.Future<Entity1>().ToList();
//Do other things here with eager loaded collections
当我查询实体1的数据库时,我得到实体1的集合的返回 - 正如我所料,然而,使用NHProf,我可以看到为每个实体2/3创建的单个查询转到数据库并单独收集它们,这意味着实体1的10行返回将触发3次查询。有没有办法批处理急切加载查询,以便代替他们每个人执行
SELECT * FROM <table> WHERE id = XXX
SELECT * FROM <table> WHERE id = YYY
SELECT * FROM <table> WHERE id = ZZZ
NHibernate将产生更像
的东西SELECT * FROM <table> WHERE id IN (XXX,YYY,ZZZ)
因此不需要多次查询数据库?
任何帮助非常感谢,如果需要更多细节,请告诉我。
答案 0 :(得分:0)
这个想法是让每个联接都在一个单独的未来查询中。你的查询很乱,所以是我的:
session.CreateCriteria<Entity1>()
.CreateCriteria("Prop3", "prop3", JoinType.InnerJoin)
.Add(Restrictions.Eq(Projections.Property("Prop2"), "Criteria!"))
.Future<Entity1>();
session.CreateCriteria<Entity1>()
.Add(Restrictions.Eq(Projections.Property("Prop2"), "Criteria!"))
.SetFetchMode("Prop2", FetchMode.Join)
.Future<Entity1>();
var query = session.CreateCriteria<Entity1>()
.Add(Restrictions.Eq(Projections.Property("Prop2"), "Criteria!"))
.SetFetchMode("Prop4", FetchMode.Join)
.Future<Entity1>();
var clients = query.ToList();