我有实体'内容'。每个内容都有一个'Placement'属性。展示位置具有多对多关系宽度“AdType”实体(展示位置已映射IList< \ AdType>属性)。
我需要加载至少在一个内容中使用的所有展示位置以及指定AdType的关联宽度。
我的DAL功能如下所示:
public IList<Placement> Load(AdType adType)
{
return NHibernateSession.QueryOver<Content>()
.JoinQueryOver(content => content.Placement)
.JoinQueryOver<AdType>(placement => placement.AdTypes)
.Where(_adType => _adType.Id == adType.Id)
.Select(x => x.Placement).List<Placement>();
}
这很好但是当我查看SQL日志时,我看到:
SELECT this_.PlacementId as y0_ FROM AdManager.dbo.[Content] this_ inner join AdManager.dbo.[Placement] placement1_ on this_.PlacementId=placement1_.PlacementId inner join AdManager.dbo.AdTypeToPlacement adtypes5_ on placement1_.PlacementId=adtypes5_.PlacementId inner join AdManager.dbo.[AdType] adtype2_ on adtypes5_.AdTypeId=adtype2_.AdTypeId WHERE adtype2_.AdTypeId = @p0
SELECT placement0_.PlacementId as Placemen1_26_0_, placement0_.Name as Name26_0_ FROM AdManager.dbo.[Placement] placement0_ WHERE placement0_.PlacementId=@p0
SELECT placement0_.PlacementId as Placemen1_26_0_, placement0_.Name as Name26_0_ FROM AdManager.dbo.[Placement] placement0_ WHERE placement0_.PlacementId=@p0
这意味着NHibernate会在第一个查询中获取所有展示位置ID,然后通过ID查询展示位置表中的所有字段。
我的问题是:enyone是否知道如何修改QueryOver方法以强制NHibernate在一个查询中加载数据?
答案 0 :(得分:0)
似乎NHibernate确实认为可能存在哪些内容可能会过滤出需要初始化放置的数据。您可以使用子查询:
public IList<Placement> Load(AdType adType)
{
var subquery = QueryOver.For<Content>()
.JoinQueryOver(content => content.Placement)
.JoinQueryOver<AdType>(placement => placement.AdTypes)
.Where(_adType => _adType.Id == adType.Id)
.Select(x => x.Id);
return NHibernateSession.QueryOver<Content>()
.WithSubquery.Where(content => content.Id).IsIn(subquery))
//.Fetch(x => x.Placement).Eager try with and without
.Select(x => x.Placement).List<Placement>();
}
或SQL(缺点是它只填充新的Placement但是会跟踪它)
public IList<Placement> Load(AdType adType)
{
return NHibernateSession.CreateSQLQuery("SELECT p.Name as Name, ... FROM content c join placement p...")
.SetResultTransformer(Transformers.AliastoBean<Placement>())
.List<Placement>();
}