Существующий открытый DataReader с использованием Entity Framework и PredicateBuilder

Хорошо, я знаю, что эта тема уже обсуждалась в тема 1, тема 2, topic 3 или тема 4 и, возможно, другие подобные темы, но почему-то я все еще чувствую, что что-то упускаю.

Что я пытаюсь сделать, так это создать фильтр с использованием Entity Framework и PredicateBuilder, который зависит от нескольких таблиц и для которого я прочитал решение Альбахари и другие темы, обсуждаемые здесь: PB 1, PB 2 или PB3.

По сути, у меня есть модель домена отеля:

    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; }
    ...
}

наличие нескольких внешних ключей. При запросе и попытке доступа к виртуальному свойству HotelType мне это легко удается.

var hotelType = Hotel.HotelType.DesiredProperty

Но когда я пытаюсь получить, например, все отели, которые имеют определенные свойства SafetyFeatures (используя построитель предикатов), я натыкаюсь на ошибку, описанную выше (уже есть открытый DataReader, связанный с этой командой, который должен быть закрыт первый).

Мой построитель предикатов выглядит примерно так:

    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.
    }

Я использую IQueryable, так как пытаюсь получить наименьшее количество данных из базы данных, поскольку я использую результат этого метода в комбинации OrderBy().Skip().Take().

Как я сказал в первых строках, я читал об этой проблеме в нескольких других темах, но я не хочу использовать MARS в качестве обходного пути, и я видел людей, предполагающих, что это возможно, но я этого не сделал. т удалось это сделать.

Я знаю, что пытаюсь перебирать элементы из нескольких таблиц в одном контексте, но разве это не то же самое, что доступ к этим свойствам, описанным в этой строке:

var hotelType = Hotel.HotelType.DesiredProperty

Нужно ли создавать дополнительный запрос, чтобы я мог получить все свои соответствующие данные из других таблиц, а затем использовать их в своем текущем PredicateBuilder?

Любой совет или соответствующая статья/книга высоко ценятся, так как я потратил некоторое время, пытаясь решить эту проблему. Спасибо!

Л.Э. SafetyFeatures — это модель, содержащая список логических значений:

    public class SafetyFeatures {
    [Key]
    public int Id { get; set; }
    public bool FireExtinguisher { get; set; }
    public bool AccessCard { get; set; }
    ...
    }

person Ionea    schedule 05.12.2016    source источник
comment
Можете ли вы опубликовать определение вашего класса SafetyFeatures? Кроме того, почему бы не сделать просто predicate = predicate.And(a => a.SafetyFeatures.FireExtinguisher) ? Любая причина?   -  person Diego    schedule 06.12.2016
comment
Я привел пример с .Equals(true) для лучшего понимания проблемы, но в любом случае я пытаюсь это сделать, но получаю ту же ошибку.   -  person Ionea    schedule 06.12.2016