Избегайте просмотра списка несколько раз с помощью linq, с динамическими условиями (фильтр)
У меня есть список с Article
объекты. Параметры для этого объекта:
Категория, описание, статус, класс
Пользователь может фильтровать список с помощью комбинации, которую он хочет. Только Описание, или Категория + Класс, и так далее.
Поэтому, если пользователь выберет критерий, я получу int >= 0, в противном случае я получу -1.
Например, если он хочет фильтровать с Status
а также Category
, Я получу
FilterCategory = x, FilterDescription = -1, FilterStatus = y, FilterClass = -1
Мой способ фильтрации списка заключается в следующем:
if (FilterCategory != -1)
list = list.Where(a => a.Category == FilterCategory);
if (FilterDescription != -1)
list = list.Where(a => a.Description == FilterDescription);
if (FilterStatus != -1)
list = list.Where(a => a.Status == FilterStatus);
if (FilterClass != -1)
list = list.Where(a => a.Class == FilterClass);
Таким образом, я должен повторить список 4 раза, это не эффективно с большим количеством элементов. Я бы просмотрел список один раз и проверил 4 условия в уникальном месте. Но я не знаю, как это сделать с определенным условием!= -1.
Спасибо
3 ответа
Вы можете сделать ОГРОМНЫЙ, где запрос переместит все ваши условия в один Where
заметив, что:
if (FilterCategory != -1)
list = list.Where(a => a.Category == FilterCategory);
эквивалентно:
list = list.Where(a => FilterCategory == -1 || a.Category == FilterCategory);
Тогда запрос:
list = list.Where(a => (FilterCategory == -1 || a.Category == FilterCategory)
&& (FilterDescription == -1 || a.Description == FilterDescription)
&& (FilterStatus == -1 || a.Status == FilterStatus)
&& (FilterClass == -1 || a.Class == FilterClass));
Но я действительно сомневаюсь, что это улучшит ваши показатели перечисления.
Как Юхарр упоминает в комментариях, Linq не будет оценивать вашу .Where
сразу после звонка. Только при звонке ToList/ToArray/First/Single/foreach
он оценит предложение и автоматически объединит ваши фильтры.
list = list.Where(a => (FilterCategory != -1 || a.Category == FilterCategory) &&
(FilterDescription != -1 || a.Description == FilterDescription) &&
(FilterStatus != -1 || a.Status == FilterStatus) &&
(FilterClass != -1 || a.Class == FilterClass));