Search code examples
nhibernatedistinctqueryover

queryover and transformusing loses the ability to lazy load


I want to try and introduce the DISTINCT keyword into SQL, basically I require the following SQL:-

SELECT distinct this_.Id          as y0_,
                this_.Name        as y1_,
                this_.Description as y2_,
                this_.UnitPrice   as y3_,
                this_.Director    as y4_
FROM   Product this_
       inner join ActorRole actor1_
         on this_.Id = actor1_.MovieId
WHERE  this_.ProductType = 'Movie'
       AND actor1_.Name like 'm%' /* @p0 */

The QueryOver code looks like this, however I can't use the DISTINCT keyword without using a projection:-

var movie = Session.QueryOver<Movie>()
  .JoinQueryOver<Actor>(m => m.ActorList).Where(a => a.Name.IsLike("m%"))
  .Select(
    Projections.Distinct(
      Projections.ProjectionList()
        .Add(Projections.Property<Movie>(w => w.Id))
        .Add(Projections.Property<Movie>(w => w.Name))
        .Add(Projections.Property<Movie>(w => w.Description))
        .Add(Projections.Property<Movie>(w => w.UnitPrice))
        .Add(Projections.Property<Movie>(w => w.Director))
      )
   )
   .TransformUsing(Transformers.AliasToBean<Movie>());
return movie.List<Movie>();

This works returns me distinct movies where actors begin with the letter 'm'. Now the problem comes as the projection is meant for DTO's and when I iterate over the results and want to lazy load the children. For example:-

@foreach (var item in Model.ActorList)
{
  <li>@(item.Name) <em>plays</em> @item.Role</li>
}

Model.ActorList is always NULL, it appears that projecting and using a transformer loses the lazy loading as this method is designed for DTO's. What are my options?

I know I can use a sub query or HQL rather than a select distinct


Solution

  • If anyone else is interested in this then please read the blog post that explains this behaviour