G+

Динамические условия AND и OR для метода Where в Linq выражениях

Программирование Asp.net
Предыдущий Следующий

Стоит задача сделать страничку поиска, на которой очень много фильтров. Фильтры между собой свзязанны условиями OR или AND. Пример интерфейса:

Сначала пришла идея воспользоваться Dynamic Linq library, где запросы можно писать в виде строк. Но я к этой библиотеке отношусь негативно, так как при изменении структуры базы данных (структуры таблиц), сложно отследить где нужно внести изменения.

По этому пришлось пользоваться лямбда-выражениями.

При создании условий отбора, мне нравится пользоваться Expression. Для примера рассмотрим фильтр по городам (будем отбирать компании по городу):

Code:

//фильтр по городам. По умолчанию фильтрации не происходит
Expression<Func<Company, bool>> filterCityID = p => true;

//Если фильтр был установлен, то меняем условие фильтрации
if (filter.SelectListCities.Any())
{
        filterCityID = p => filter.SelectListCities.Contains(p.CityID);
}
var result = datacontext.Companies.Where(filterCityID).ToList()

 

Теперь перейдем к написанию условия AND между фильтрами. Для этого нужно понимать что такое Lazy Load - поздняя загрузка. Все очень просто. Когда мы пишем код: datacontext.Companies.Where(p=>p.CityID == 10) то запрос к БД будет происходить только после вызова метода ToList. Это означает, что мы можем писать вот так:

var result = datacontext.Companies.Where(p=>p.CityID == 10);

if(filter.SelectListSeti)
{
    result = result.Where(p=> filter.SelectListSeti.Contains( p.SetiID ));
}
var data = result.ToList();

В этом коде мы к фильтру CityID == 10 добавляем еще фильтр по сетям. Или другим языком выполняем условие AND.

 

Теперь рассмотрим условие OR:

var result = datacontext.Companies.Where(p=>p.CityID == 10);

if(filter.SelectListSeti)
{
    result = result.Union ( datacontext.Companies.Where(p=> filter.SelectListSeti.Contains(p.SetiID)));
}
var data = result.ToList();

Запрос будет весьма тяжелый, но другого я пока не придумал.

 

Комментарий:
  • В 08.11.2011 17:40:02, Аноним

    Надо смотреть в глубину Expression. Там можно много чего делать. Лепить логику с AND и OR

Самостоятельный отпуск Опыт заказа вывоза мусора в Киеве