Search code examples
c#linq-query-syntax

"Expression type 'NhDistinctExpression' is not supported by this SelectClauseVisitor." - with Query Syntax


Given the following expression, how do I go about getting a distinct list of venues, without getting that nasty "Expression type 'NhDistinctExpression' is not supported by this SelectClauseVisitor." error?

    public Dictionary<int, string> GetScheduledVenuesFuture()
    {
        var venues = from v in _sp.CurrentSessionOn(DatabaseName.MyDB).Query<Venue>()
                     join s in _sp.CurrentSessionOn(DatabaseName.MyDB).Query<ScheduledClass>()
                             on v.VenueId equals s.Venue.VenueId
                     where s.CourseDate >= _cac.Now
                             && s.Closed == false
                             && s.Canceled == false

                     select new
                     {
                         v.VenueId,
                         v.Name
                     };

        return venues.ToDictionary(v => v.VenueId, v => v.Name);
    }

I've tried setting

        return venues.ToDictionary(v => v.VenueId, v => v.Name);

as distinct by doing:

        return venues.Distinct().ToDictionary(v => v.VenueId, v => v.Name);

but that throws the error. I also tried surrounding the entire query syntax statement in parens, and putting a .Distinct() at the end of it, but that also resulted in the same error.


Solution

  • I wound up solving this another way:

        public class ScheduledVenueDTO
        {
            public int VenueId { get; set; }
            public string Name { get; set; }
        }
    
        public Dictionary<int, string> GetScheduledVenuesFuture()
        {
            var venues = from v in _sp.CurrentSessionOn(DatabaseName.SMS).Query<Venue>()
                         join s in _sp.CurrentSessionOn(DatabaseName.SMS).Query<ScheduledClass>()
                                 on v.VenueId equals s.Venue.VenueId
                         where s.CourseDate >= _cac.Now
                                 && s.Closed == false
                                 && s.Canceled == false
                         select new
                         {
                             v.VenueId,
                             v.Name
                         };
    
            var svd = venues
                .GroupBy(v => new { v.VenueId, v.Name})
                .Select(v => new ScheduledVenueDTO() {
                    VenueId = v.Key.VenueId,
                    Name = v.Key.Name
                });
    
            return svd.ToDictionary(v => v.VenueId, v => v.Name);
        }
    

    I simply created a new DTO, and with a groupBy, injected that DTO with only distinct venues.