简体   繁体   中英

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.QueryOver<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>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM