Search code examples
nhibernatejoindistinctqueryover

QueryOver with Join and Distinct


I use the follow QueryOver:

var query = searchTermRepository.GetAllOver()
     .Where(Restrictions.On<Entities.SearchTerm>(c => c.Text).IsLike(filter.Value, MatchMode.Start))
     .Select(Projections.Distinct(Projections.Property<Entities.SearchTerm>(x => x.Contact)))
     .Inner.JoinQueryOver(x => x.Contact).Take(100);

This creates:

SELECT distinct TOP ( 100 /* @p0 */ ) this_.ContactId as y0_
FROM   SearchTerm this_
       inner join Contact contact1_
         on this_.ContactId = contact1_.Id
       left outer join Company contact1_1_
         on contact1_.Id = contact1_1_.Id
       left outer join Person contact1_2_
         on contact1_.Id = contact1_2_.Id
       left outer join Branch contact1_3_
         on contact1_.Id = contact1_3_.Id
       left outer join ContactGroup contact1_4_
         on contact1_.Id = contact1_4_.Id
WHERE  this_.Text like 'koc%%' /* @p1 */

But I want

SELECT distinct TOP ( 100 /* @p0 */ )  this_.ContactId as y0_, contact1_.*
FROM   SearchTerm this_
       inner join Contact contact1_
         on this_.ContactId = contact1_.Id
       left outer join Company contact1_1_
         on contact1_.Id = contact1_1_.Id
       left outer join Person contact1_2_
         on contact1_.Id = contact1_2_.Id
       left outer join Branch contact1_3_
         on contact1_.Id = contact1_3_.Id
       left outer join ContactGroup contact1_4_
         on contact1_.Id = contact1_4_.Id
WHERE  this_.Text like 'koc%%' /* @p1 */

I want select all Properties of Contact.

Best Regards, Thomas


Solution

  • You do have to explicitly specify all of the columns that you want to project. There's no way around this that I know of.

    Here's some quick code off the top of my head that uses QueryOver:

    Contact contact = null;
    
    Session
    .QueryOver(() => contact)
    .SelectList(list => list
        .Select(Projections.Distinct(Projections.Property(x => x.Contact))) 
        .Select(c => c.Id).WithAlias(() => contact.Id)
        .Select(c => c.FirstName).WithAlias(() => contact.FirstName)
    ... and so on
    

    You'll then need to transform this to your object using the AliasToBean transformer.