I have tasks in my system and created special class for searching:
public class TaskSearchCriteria
{
public List<int> Statuses { get; set; }
public List<int> Severities { get; set; }
public List<int> CreatedBy { get; set; }
public List<int> ClosedBy { get; set; }
public List<int> LastModificationBy { get; set; }
public DateTime? CreationDateFrom { get; set; }
public DateTime? CreationDateTo { get; set; }
public bool SearchInComments { get; set; }
public bool SearchInContent { get; set; }
public bool SearchInTitle { get; set; }
}
One method in that class applies filters:
public IQueryable<Task> Filter(IQueryable<Task> tasks)
{
return
FilterDates(
FilterAssignedTo(
FilterGroups(
FilterOperationSystems(
FilterPlatforms(
FilterPriorities(
FilterSeverities(
FilterVersionsResolved(
FilterVersionsReported(
FilterTaskContent(
FilterStatuses(tasks)))))))))));
}
This is one of methods used for filtering:
private IQueryable<Task> FilterSeverities(IQueryable<Task> tasks)
{
if (Severities.Contains(TaskSearchConsts.All) || (!Severities.Any()))
return tasks;
var expressions = new List<Expression>();
if (Severities.Contains(TaskSearchConsts.Active))
expressions.Add(_taskParameter.EqualExpression("Severity.IsActive", 1));
return tasks.WhereIn(_taskParameter, "Severity.ID", Severities, expressions);
}
This is Entity Framework, but it can be easily done in nHibernate too by adding where clauses to IQuery.
To search I have a method in controller:
[HttpPost]
public ActionResult TaskSearch([Bind(Prefix = "Search")]TaskSearchCriteria criteria)
Having one class for filtering is nice, because it can be serialized and save to database for future use. This way user can reuse filter parameters.
You would have:
public class CarSearchCriteria
{
List<int> ListOfCarTypesIds;
List<int> ListOfCarBrandIds;
bool IsNew;
//and more
}
If list is empty, you don't apply filter.