NHibernate QueryOver Select only needed model
I've encountered a little problem selecting only the needed model in QueryOver. Here my scenario
var qOver = _HibSession.QueryOve开发者_运维知识库r<ModelA>(() => Ma)
.JoinAlias(() => Ma.MbList, () => Mb, JoinType.LeftOuterJoin)
.Where(() => Mb.ID == _MbId)
.JoinAlias(() => Mb.McList, () => Mc,JoinType.LeftOuterJoin)
.Where(() => Mc.ID == _McId)
.JoinAlias(() => Mc.MdList, () => Md, JoinType.LeftOuterJoin)
.Where(() => Md.ID == _MdID)
.OrderByAlias(() => Ma.ID).Asc
.Take(iTake)
.Skip(iSkip)
.Future<ModelA>();
The previous code generate the follow SQL
SELECT TOP n Ma.*,Mb.*,Mc.*,Md.*
FROM Ma
LEFT JOIN Mb ON (...conditions...)
LEFT JOIN Mc ON (...conditions...)
LEFT JOIN Md ON (...conditions...)
WHERE Mb.ID = _MbId
AND Mc.ID = _McId
AND Md.ID = _MdId
ORDER BY Ma.ID ASC
The problem is that Mc and Md table duplicates my result. So I would have only Ma and Mb in my SELECT statement.
SELECT TOP n Ma.*,Mb.*
FROM
.
.
.
How can I reach that result? Thank you!
Try using Fetch
instead of JoinAlias
. Something like this should do the job:
... .QueryOver<Ma>().Fetch(ma => ma.MbList).Eager
and do not use fetch="join"
in your mapping.
When you force NHibernate to use join
, it will return as many rows as there are in the cartesian product of your tables. As you only need one list item per ModelA object, you have to let NHibernate use simple select
statements instead of join
.
You need to inform NHibernate to not repeat the root entity (ModelA). You can do this with the statement:
.TransformUsing(Transformers.DistinctRootEntity)
It seems the only way is to use a pricipal QueryOver selecting the main model and a filtered SubQuery
I mean something like this
var qOverInclude = QueryOver.Of<MyModel>(() => mModel)
.JoinAlias(() => mModel.MyList, () => mList, JoinType.LeftOuterJoin)
.Where(() => mList.ID == myID)
.And(() => mList.Type == myType)
.Select(x => x.IdMyModel);
var qOver = _HibSession.QueryOver<MyModel>(() => mModel)
.JoinAlias(() => mModel.MyDescription, () => mDescription, JoinType.LeftOuterJoin)
.Where(() => mDescription.IDLanguage == myLanguage)
.WithSubquery.WhereProperty(() => mModel.IdMyModel).In(qOverSubQuery)
.OrderByAlias(() => mModel.IdMyModel).Asc
.Future<MyModel>();
精彩评论