0

Ok, I know that this topic has already been discussed in topic 1, topic 2, topic 3 or topic 4 and probably other similar topics, but somehow, I still feel I'm missing something.

What I'm trying to do is to create a filter using Entity Framework and a PredicateBuilder that depends on several tables, and for which I've read Albahari's solution and other topics discussed here: PB 1, PB 2 or PB3.

Basically, I have an Hotel domain model:

    public class Hotel
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public int? Capacity { get; set; }
    public int? SafetyFeatureId { get; set; }
    public int HotelTypeId { get; set; }
    ...

    [ForeignKey("SafetyFeatureId")]
    public virtual SafetyFeatures SafetyFeatures { get; set; }
    [ForeignKey("HotelTypeId")]
    public virtual HotelType HotelType { get; set; }
    ...
}

having several foreign keys. When querying and trying to access the HotelType virtual property, I manage to do so easily

var hotelType = Hotel.HotelType.DesiredProperty

But when I'm trying to get, for instance, all the hotels that are having certain SafetyFeatures properties (using the predicate builder), I stumble upon the error described above (There is already an open DataReader associated with this Command which must be closed first).

My predicate builder looks something like this:

    private IQueryable<Hotel> FilterHotels(IQueryable<Hotel> hotels, HotelFilter filter)
    {
    ...
    if (filter.MinCapacity.HasValue)
            predicate = predicate.And(a => a.Capacity.Value >= filter.MinCapacity.Value);
    //no problem here, as I use property from Hotel

    if (useHotelTypeFilter)
        {
            hotelTypePredicate = GetHotelTypePredicate(hotelTypePredicate, filter.HotelTypes);
            predicate = predicate.And(hotelTypePredicate);
        } 
    //works great, because GetHotelTypePredicate checks the "Selected" property from filter.HotelTypes and then uses HotelType id to build the predicate.
    ...

    if (filter.SafetyFeatures != null && filter.SafetyFeatures.FireExtinguisher)
            predicate = predicate.And(a => a.SafetyFeatures.FireExtinguisher.Equals(true));
    //this is the part of the code that throws the error.
    }

I'm using IQueryable as I'm trying to get the least amount of data out of the db, as I use the result of this method in an OrderBy().Skip().Take() combo.

As I've said in the opening lines, I've read about the problem in other several topics, but I'm not willing to use MARS as a workaround and I've seen people suggesting that this is possible, but I haven't managed to do so.

I'm aware that I'm trying to iterate on elements from several tables inside the same context, but isn't it the same as accessing those properties described in this line:

var hotelType = Hotel.HotelType.DesiredProperty

Is it necessary to create an additional query so I can retrieve all my relevant data from other tables and then use it in my current PredicateBuilder?

Any piece of advice or relevant article/book is highly appreciated, as I've spent some time trying to solve this. Thank you!

L.E. SafetyFeatures is a model containing a list of bools:

    public class SafetyFeatures {
    [Key]
    public int Id { get; set; }
    public bool FireExtinguisher { get; set; }
    public bool AccessCard { get; set; }
    ...
    }
Community
  • 1
  • 1
Ionea
  • 33
  • 1
  • 8
  • Can you post the definition of your `SafetyFeatures` class? Also, why not doing just `predicate = predicate.And(a => a.SafetyFeatures.FireExtinguisher)` ? Any reason? – Diego Dec 06 '16 at 01:30
  • I've let the example with .Equals(true) for a better understanding of the problem, but either way I try to do it I get the same error. – Ionea Dec 06 '16 at 08:30

0 Answers0