2015-12-15 3 views
1

Я пишу метод, который возвращает коллекцию ProductPeriod объектов на основе следующих фильтров:C# фильтрации коллекции объектов

DateTime? from 
DateTime? to 
bool? includeActive 
bool? includeInactive 

Объект ProductPeriod выглядит следующим образом:

public class ProductPeriod 
{ 
    public int Id { get; set; } 
    public string Name 
    public DateTime StartDate { get; set; } 
    public DateTime EndDate { get; set; } 
    public bool IsActive { get; set; } 
} 

Так идея заключается в том, что клиент может выбрать дату и/или дату и/или включить активные периоды и/или включить неактивные периоды. Это дает довольно много сценариев для фильтрации, что делает довольно большой метод, который я начал писать (и еще не закончить):

public IEnumerable<ProductPeriod> GetFilteredProductPeriods(DateTime? from,  DateTime? to, bool? includeActive, bool? includeInactive) 
{    
    // 1. from date only 
    if(from.HasValue && to == null && includeActive == null && includeInactive == null) 
     return _entities.ProductPeriods.Where(x => x.StartDate >= from.Value).ToList(); 

    // 2. from and to date 
    if(from.HasValue && to.HasValue && includeActive == null && includeInactive == null) 
     return _entities.ProductPeriods.Where(x => x.StartDate >= from.Value && x.EndDate <= to.Value).ToList(); 

    // 3. to date only 
    if (to.HasValue && from == null && includeActive == null && includeInactive == null) 
     return _entities.ProductPeriods.Where(x => x.EndDate <= to.Value).ToList(); 

    // 4. from date and show active 
    if (from.HasValue && (includeActive != null && includeActive.Value) && to == null && includeInactive == null) 
     return _entities.ProductPeriods.Where(x => x.StartDate >= from.Value && x.IsActive).ToList(); 

    // 5. from, to and show active 
    if (from != null && to != null && (includeActive != null && includeActive.Value) && includeInactive == null) 
     return _entities.ProductPeriods.Where(x => x.StartDate >= from.Value && x.EndDate <= to.Value && x.IsActive).ToList(); 

    // 6. to date and show active 
    if (to.HasValue && (includeActive != null && includeActive.Value) && from == null && includeInactive == null) 
     return _entities.ProductPeriods.Where(x => x.EndDate <= to.Value && x.IsActive).ToList(); 

    // 7. .... and so on, so forth.. 
} 

мне интересно, если есть лучше/умнее способ сделать это, что я не знаю? То есть какой-то общий путь? :-)

Заранее спасибо.

+0

Вы можете связать 'Where()' s, который будет 'AND'ed. Вы можете сделать это, если объявите 'IQueryable '. См. [Дубликат (второй ответ)] (http://stackoverflow.com/questions/5787794/linq-adding-where-clause-only-when-a-value-is-not-null), [структура сущности: условный фильтр ] (http://stackoverflow.com/questions/11465772/entity-framework-conditional-filter), [Linq: добавление условий в предложение where условно] (http://stackoverflow.com/questions/10884651/linq-adding -conditions-to-the-where-clause-условно) и так далее. Изменить: outSkeeted again ... – CodeCaster

ответ

3

Да, определенно лучший способ. Вы должны использовать таким образом, что запросы могут быть построены в LINQ:

public IEnumerable<ProductPeriod> GetFilteredProductPeriods 
    (DateTime? from, DateTime? to, bool? includeActive, bool? includeInactive) 
{ 
    IQueryable<ProductPeriod> query = _entities.ProductPeriods; 
    if (from != null) 
    { 
     query = query.Where(x => x.StartDate >= from.Value); 
    } 
    if (to != null) 
    { 
     query = query.Where(x => x.EndDate >= to.Value); 
    } 
    if (includeActive == false) 
    { 
     query = query.Where(x => !x.IsActive); 
    } 
    if (includeInactive == false) 
    { 
     query = query.Where(x => x.IsActive); 
    } 
    return query.ToList(); 
} 

Обратите внимание, что установка includeInactive=false и includeActive=false не даст вам никаких результатов ... Вы можете изменить его на один параметр, который является false (только неактивный), true (только активно), null (все).

+0

Это потрясающе! :-) Большое спасибо, Джон. Узнал что-то новое сегодня! –

+1

@Silvermind: Нет, у меня есть 'includeInactive == false' и' includeActive == false'. Для частей 'from.Value' ... возможно, но я думаю, что это яснее. –

+0

Я полностью его прочитал. Кажется, это неоднозначно для меня. – Silvermind

Смежные вопросы