I\'ve looked at the similar questions, but can\'t find a simple explanation. I could have missed it, but I promise I looked. Actually I can\'t even find the documentation ot
Well, hashed at this some more, and while I don't like one part of the results, it does work:
var distinctProgIdsSubQuery = QueryOver.Of().
JoinQueryOver(p => p.Topics).
WhereRestrictionOn(pt => pt.Id).IsIn(topicIds)
.Select(Projections.Distinct(Projections.Property(p => p.Id)));
ProgramDTO pDTO = null;
var progQuery = Session.QueryOver()
.WithSubquery.WhereProperty(p => p.Id).In(distinctProgIdsSubQuery)
.SelectList(list => list
.Select(program => program.Id).WithAlias(() => pDTO.Id)
.Select(...)
)
.TransformUsing(Transformers.AliasToBean(typeof(ProgramDTO)));
return progQuery.List();
This produces
SELECT this_.ProgramId as y0_, ...
FROM Programs this_
WHERE this_.ProgramId in (
SELECT distinct this_0_.ProgramId as y0_
FROM
Programs this_0_
inner join
Programs_Topics topics3_
on this_0_.ProgramId=topics3_.ProgramId
inner join
Topics topic1_
on topics3_.TopicId=topic1_.TopicId
WHERE
topic1_.TopicId in (
@p1, @p2, ...
)
)
This may be a limitation of NH, but there's no need to join the Programs table in the subquery. I tried to write this from the other direction -- that is, to create a QueryOver.Of
, but I could not figure out how to select the program IDs at the end -- select was only giving me the TopicIds, and even then the query was still joining all three tables.
I'm not sure if MS-SQL's query optimizer will avoid the useless join or not, but it would be nice if we didn't have to rely on it.
For now though, this works, and hopefully someone else has fewer headaches than I did trying to figure this out.