Хорошо, я знаю, что эта тема уже обсуждалась в тема 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; }
...
}
SafetyFeatures
? Кроме того, почему бы не сделать простоpredicate = predicate.And(a => a.SafetyFeatures.FireExtinguisher)
? Любая причина? - person Diego   schedule 06.12.2016