4

I have a simple query.

It checks for a list of rooms - prebookedRooms

It then checks for another list of rooms, but uses the .Except operator, to remove any prebookedRooms from the subsequent list:

        // Get list of rooms already booked
        var prebookedRooms = dbt.Rooms
            .Where(room => room.Rentals.Any(rental =>
                (dteFrom >= rental.check_in && dteFrom < rental.check_out)));

        // Get list of rooms
        var rooms = dbt.Rooms.Where(r => r.h_id == AccID)
            .Except(prebookedRooms)
            .GroupBy(p => p.RoomTypes).Select(g => new RatesViewModel
            {
                TypeName = g.Key.t_name,
                TypeID = g.Key.t_id,
                TypeCount = g.Count()
            })
            .ToList();

This works fine - with rooms returning a list of rooms, with prebookedRooms excluded.

However, if prebookedRooms doesn't return any records (ie. Empty "Enumeration yielded no results") - then I get an error when executing the second query (var rooms = ...):

The cast to value type 'Int64' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.

Is there anyway of checking if prebookedRooms is empty, within the second query, so I can avoid this error?

prebookedRooms model:

public class Room
{
    [Key]
    public long room_id { get; set; }
    public long hotel_id { get; set; }
    public long type_id { get; set; }
}

The error as it appears in VS is: enter image description here

Thank you,

Mark

4
  • Is there any reason you can't split the query and test if the result of dbt.Rooms.Where(r => r.h_id == AccID).Except(prebookedRooms) isn't null before trying the .GroupBy?
    – ChrisF
    Commented Jun 1, 2013 at 15:59
  • Hi - rooms will always return records - it's only when prebookedRooms has no records, that the rooms query fails. Thanks, Mark
    – Mark
    Commented Jun 1, 2013 at 16:03
  • That's my point - by splitting the query at the Except you can check it's not null before doing the GroupBy.
    – ChrisF
    Commented Jun 1, 2013 at 16:05
  • How do I split the query though? I'm not sure how to do it, and then continue with the GroupBy afterwards.
    – Mark
    Commented Jun 1, 2013 at 16:17

2 Answers 2

1

Can't you just resign from Except and write:

    var rooms = dbt.Rooms.Where(r => r.h_id == AccID)
        .Where(room => !room.Rentals.Any(rental =>
            (dteFrom >= rental.check_in && dteFrom < rental.check_out))).
        .GroupBy(p => p.RoomTypes).Select(g => new RatesViewModel
        {
            TypeName = g.Key.t_name,
            TypeID = g.Key.t_id,
            TypeCount = g.Count()
        })
        .ToList();
0

Try using the null coalescing operator: ?? and then getting the IQueryable<T> equivalent of Enumerable<T>.Empty, which is Enumerable<T>.Empty().AsQueryable() and DefaultIfEmpty with an invalid room, so it doesn't go crazy about it being null || empty:

    var rooms = dbt.Rooms.Where(r => r.h_id == AccID)
        .Except(prebookedRooms ?? Enumerable.Empty<T>().AsQueryable().DefualtIfEmpty(new Room() { room_id = -1, hotel_id = -1, type_id = -1}))
        .GroupBy(p => p.RoomTypes).Select(g => new RatesViewModel
        {
            TypeName = g.Key.t_name,
            TypeID = g.Key.t_id,
            TypeCount = g.Count()
        })
        .ToList();

I don't know your type, so I don't know what to put in the Enumerable.Empty<T> call's generic parameter. Add that yourself.

Also, remember to be using System.Linq!

12
  • Thank you for the suggestion. Unfortunately it had no effect (I did add the correct type - but prebookedRooms still "yielded no results" and when the second query was run, the error remained.
    – Mark
    Commented Jun 1, 2013 at 16:15
  • That's pretty weird... means it treats empty collections as null. Commented Jun 1, 2013 at 16:20
  • I tried adding the ?? in the second query, as per your update above - but still I get the same error.
    – Mark
    Commented Jun 1, 2013 at 16:20
  • @fixit Is there one value that will never be in the DB and you could therefore safely pass it to DefaultIfEmpty, so then it won't throw that weird error? Commented Jun 1, 2013 at 16:25
  • Hi - I've been checking that out - preBookedRooms would hold a collection of long, long, long - eg. 1245,56,3 - how would I enter that into DefaultIfEmpty() - DefaultIfEmpty(1245,56,3) isn't allowed. Thank you again.
    – Mark
    Commented Jun 1, 2013 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.