private bool RecordMatch(FundraisingMenuResult r, DataTableParameters query) { IEnumerable<ColumnData> validColumns = query.columns.Where(c => !String.IsNullOrEmpty(c.data)); // Check for a column search value match. IEnumerable<ColumnData> columnsWithQueries = validColumns .Where(c => !String.IsNullOrEmpty(c.search.value)); bool filterMatch = columnsWithQueries.Count() == 0 || columnsWithQueries.Select(delegate(ColumnData c) { bool match = false; SearchParameters searchParams = JsonConvert.DeserializeObject<SearchParameters>(c.search.value); if (searchParams.payload.Count > 0) { if (_dataMap.ContainsKey(c.data)) { foreach (string searchValue in searchParams.payload) { match = match || _dataMap[c.data].TextSearchMatch(searchValue, r); } } } return match; }).Aggregate(false, (a, b) => a || b); // Check for a text search value match in all columns bool textSearchMatch = String.IsNullOrEmpty(query.search.value) || validColumns.Select(delegate(ColumnData c) { return _dataMap.ContainsKey(c.data) && _dataMap[c.data].TextSearchMatch(query.search.value, r); }).Aggregate(false, (a, b) => a || b); return filterMatch && textSearchMatch; }
/// <summary> /// Order menu records. This function always orders first by package. /// </summary> /// <param name="allProjects"></param> /// <param name="parameters"></param> /// <returns></returns> private List<FundraisingMenuResult> OrderProjectRecords(List<FundraisingMenuResult> allProjects, DataTableParameters parameters) { IOrderedEnumerable<FundraisingMenuResult> orderedData = allProjects .OrderBy(r => r.ProjectPackage[0].Priority) .ThenBy(r => r.ProjectPackage[0].PackageName); foreach (var orderByClause in parameters.order) { var evalFunc = EvaluateOrderBy(orderByClause.column, parameters.columns); if (evalFunc != null) { bool asc = orderByClause.dir == OrderingData.OrderingDirection.asc; orderedData = asc ? orderedData.ThenBy(evalFunc) : orderedData.ThenByDescending(evalFunc); } } return orderedData.ToList(); }
public DataTableResult<FundraisingMenuResult> SearchSortAndFilter(DataTableParameters query) { DataTableResult<FundraisingMenuResult> result = GetAllFundraisingMenuProjects(); // Add virtual projects for packages containing no projects. AddVirtualProjects(result.data); // Expand by package. result.data = ExpandByPackage(result.data); result.draw = query.draw; result.recordsTotal = result.data.Where(r => r.HubId != null).Count(); // Search result.data = result.data.Where(r => RecordMatch(r, query)).ToList(); result.recordsFiltered = result.data.Where(r => r.HubId != null).Count(); // Order result.data = OrderProjectRecords(result.data, query); // Page result.data = PageResults(query, result.data); return result; }
/// <summary> /// We need to use a more advanced paging strategy because there /// are virtual records that will not be displayed in the table. /// So instead of using the start and length arguments from the /// query as a hard Skip/Take boundary, we need to count how many /// virtual records preceeded the current page and we need to take /// records up to the query length, but excluding virtual records /// from the count. /// </summary> /// <param name="query"></param> /// <param name="data"></param> /// <returns></returns> private static List<FundraisingMenuResult> PageResults(DataTableParameters query, List<FundraisingMenuResult> data) { // Count how many "virtual" records there are before the page begins int virtualRecordsBeforeStart = data.Take(query.start).Where(r => r.HubId == null).Count(); // That's our starting point. IEnumerable<FundraisingMenuResult> recordsFromStart = data.Skip(query.start + virtualRecordsBeforeStart); // Take an initial set of records using the page size. IEnumerable<FundraisingMenuResult> pagedResult = recordsFromStart.Take(query.length); // Take more records until we have query.length real records or we hit the end of the list. int totalLength = recordsFromStart.Count(); int currentCount = pagedResult.Count(); int virtualCount = pagedResult.Where(r => r.HubId == null).Count(); while (currentCount - virtualCount < query.length && currentCount + virtualCount < totalLength) { pagedResult = recordsFromStart.Take(currentCount + virtualCount); currentCount = pagedResult.Count(); virtualCount = pagedResult.Where(r => r.HubId == null).Count(); } return pagedResult.ToList(); }
public ActionResult SearchData(DataTableParameters parameters) { FundraisingMenuSearchServices _fmss = new FundraisingMenuSearchServices(); DataTableResult<FundraisingMenuResult> result = _fmss.SearchSortAndFilter(parameters); return Json(result); }