在NHibernate中设置fetchmode并没有消除SELECT N+;1期
我正在为一些相当基本的东西而挣扎。我有一个一对多关系,在我的条件查询中将fetchmode设置为internaljoin。我看到生成的SQL包含连接,但它也懒散地获取子实体。我做错了什么 映射(行业中有许多制造商):在NHibernate中设置fetchmode并没有消除SELECT N+;1期,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我正在为一些相当基本的东西而挣扎。我有一个一对多关系,在我的条件查询中将fetchmode设置为internaljoin。我看到生成的SQL包含连接,但它也懒散地获取子实体。我做错了什么 映射(行业中有许多制造商): 我复制了您的场景,只做了一些小改动,结果与预期一致。检查以下各项: 域类: public class Industry { public virtual int ID { get; set; } public virtual string Name { get; s
我复制了您的场景,只做了一些小改动,结果与预期一致。检查以下各项: 域类:
public class Industry
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<Manufacturer> Manufacturers { get; set; }
}
public class Manufacturer
{
public virtual int ID { get; set; }
public virtual string Name { get; set; }
public virtual Industry Industry { get; set; }
}
公共级行业
{
公共虚拟整数ID{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟ICollection制造商{get;set;}
}
公共类制造商
{
公共虚拟整数ID{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟产业产业{get;set;}
}
映射:
public class IndustryMap : ClassMap<Industry>
{
public IndustryMap()
{
Id(industry => industry.ID);
Map(industry => industry.Name);
HasMany(x => x.Manufacturers)
.KeyColumn("IndustryID")
.AsSet()
.Inverse()
//.Access.PascalCaseField(Prefix.Underscore)
.LazyLoad();
}
}
public class ManufacturerMap : ClassMap<Manufacturer>
{
public ManufacturerMap()
{
Id(manufacturer => manufacturer.ID);
Map(manufacturer => manufacturer.Name);
References(manufacturer => manufacturer.Industry, "IndustryID")
.LazyLoad();
}
}
公共类行业地图:类地图
{
公共行业地图()
{
Id(industry=>industry.Id);
Map(industry=>industry.Name);
有许多(x=>x.0个制造商)
.KeyColumn(“IndustryID”)
1.资产()
.Inverse()
//.Access.PascalCaseField(前缀.下划线)
.LazyLoad();
}
}
公共类制造商映射:类映射
{
公共制造商MAP()
{
Id(制造商=>manufacturer.Id);
映射(manufacturer=>manufacturer.Name);
参考(制造商=>制造商.行业,“行业ID”)
.LazyLoad();
}
}
查询:
var industries = this.Session.CreateCriteria<Industry>()
.CreateAlias("Manufacturers", "manu", JoinType.InnerJoin)
.AddOrder(new Order("Name", true))
.SetResultTransformer(new DistinctRootEntityResultTransformer())
.List<Industry>();
var industries = session.CreateCriteria<Industry>()
.SetFetchMode("Manufacturers", FetchMode.Eager) //this is it
.List<Industry>();
var industries=session.CreateCriteria()
.SetFetchMode(“制造商”,FetchMode.Eager)//就是这样
.List();
更新:
按制造商查询订单。名称:
var industries = session.CreateCriteria<Industry>()
.SetFetchMode("Manufacturers", FetchMode.Eager) //this is it
.CreateAlias("Manufacturers","manu")
.AddOrder(Order.Asc("manu.Name")
.List<Industry>();
var industries=session.CreateCriteria()
.SetFetchMode(“制造商”,FetchMode.Eager)//就是这样
.CreateAlias(“制造商”、“制造商”)
.AddOrder(Order.Asc(“制造商名称”)
.List();
我在我的代码中一步一步地复制了您所做的更改,结果显示.SetFetchMode是不同的。SetFetchMode和.CreateAlias之间有什么区别?我的印象是它们应该做同样的事情。CreateAlias允许您向相关实体添加条件,类似于表中的联接,“FetchMode”在CreateAlias中,方法只是为了确保它将是一个内部连接或左外部连接。SetFetchMode告诉NHibernate要懒洋洋地或急切地对待该属性。哇。大灯泡刚刚熄灭。不是为了看起来像一匹送礼的马,而是我如何才能在Manufacturer.Name上的同一查询中添加订单语句?我复制了您的查询代码并当我浏览记录时,CreateAlias行触发N+1。当我注释掉CreateAlias和AddOrder时,它工作得非常好。
var industries = session.CreateCriteria<Industry>()
.SetFetchMode("Manufacturers", FetchMode.Eager) //this is it
.List<Industry>();
var industries = session.CreateCriteria<Industry>()
.SetFetchMode("Manufacturers", FetchMode.Eager) //this is it
.CreateAlias("Manufacturers","manu")
.AddOrder(Order.Asc("manu.Name")
.List<Industry>();