private IQueryable <TEntity> ApplySorting <TEntity>( ISieveModel <IFilterTerm, ISortTerm> model, IQueryable <TEntity> result, object[] dataForCustomMethods = null) { if (model?.SortsParsed == null) { return(result); } var useThenBy = false; foreach (var sortTerm in model.SortsParsed) { var property = GetSieveProperty <TEntity>(true, false, sortTerm.Name); if (property != null) { result = result.OrderByDynamic(property.Name, sortTerm.Descending, useThenBy); } else { result = ApplyCustomMethod(result, sortTerm.Name, _customSortMethods, new object[] { result, useThenBy, sortTerm.Descending }, dataForCustomMethods); } useThenBy = true; } return(result); }
/// <summary> /// Apply filtering, sorting, and pagination parameters found in `model` to `source` /// </summary> /// <typeparam name="TEntity"></typeparam> /// <param name="model">An instance of ISieveModel</param> /// <param name="source">Data source</param> /// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param> /// <param name="applyFiltering">Should the data be filtered? Defaults to true.</param> /// <param name="applySorting">Should the data be sorted? Defaults to true.</param> /// <param name="applyPagination">Should the data be paginated? Defaults to true.</param> /// <returns>Returns a transformed version of `source`</returns> public IQueryable <TEntity> Apply <TEntity>( ISieveModel <IFilterTerm, ISortTerm> model, IQueryable <TEntity> source, object[] dataForCustomMethods = null, bool applyFiltering = true, bool applySorting = true, bool applyPagination = true) { var result = source; if (model == null) { return(result); } try { // Filter if (applyFiltering) { result = ApplyFiltering(model, result, dataForCustomMethods); } // Sort if (applySorting) { result = ApplySorting(model, result, dataForCustomMethods); } // Paginate if (applyPagination) { result = ApplyPagination(model, result); } return(result); } catch (Exception ex) { if (_options.Value.ThrowExceptions) { if (ex is SieveException) { throw; } throw new SieveException(ex.Message, ex); } else { return(result); } } }
private IQueryable <TEntity> ApplyPagination <TEntity>( ISieveModel <IFilterTerm, ISortTerm> model, IQueryable <TEntity> result) { var page = model?.Page ?? 1; var pageSize = model?.PageSize ?? _options.Value.DefaultPageSize; var maxPageSize = _options.Value.MaxPageSize > 0 ? _options.Value.MaxPageSize : pageSize; result = result.Skip((page - 1) * pageSize); if (pageSize > 0) { result = result.Take(Math.Min(pageSize, maxPageSize)); } return(result); }
private IQueryable <TEntity> ApplyFiltering <TEntity>( ISieveModel <IFilterTerm, ISortTerm> model, IQueryable <TEntity> result, object[] dataForCustomMethods = null) { if (model?.FiltersParsed == null) { return(result); } Expression outerExpression = null; var parameterExpression = Expression.Parameter(typeof(TEntity), "e"); foreach (var filterTerm in model.FiltersParsed) { Expression innerExpression = null; foreach (var filterTermName in filterTerm.Names) { var property = GetSieveProperty <TEntity>(false, true, filterTermName); if (property != null) { var converter = TypeDescriptor.GetConverter(property.PropertyType); dynamic constantVal = converter.CanConvertFrom(typeof(string)) ? converter.ConvertFrom(filterTerm.Value) : Convert.ChangeType(filterTerm.Value, property.PropertyType); Expression filterValue = GetClosureOverConstant(constantVal, property.PropertyType); dynamic propertyValue = Expression.PropertyOrField(parameterExpression, property.Name); if (filterTerm.OperatorIsCaseInsensitive) { propertyValue = Expression.Call(propertyValue, typeof(string).GetMethods() .First(m => m.Name == "ToUpper" && m.GetParameters().Length == 0)); filterValue = Expression.Call(filterValue, typeof(string).GetMethods() .First(m => m.Name == "ToUpper" && m.GetParameters().Length == 0)); } if (innerExpression == null) { innerExpression = GetExpression(filterTerm, filterValue, propertyValue); } else { innerExpression = Expression.Or(innerExpression, GetExpression(filterTerm, filterValue, propertyValue)); } } else { var parameters = new object[] { result, filterTerm.Operator, filterTerm.Value }; result = ApplyCustomMethod(result, filterTermName, _customFilterMethods, parameters, dataForCustomMethods); } } if (outerExpression == null) { outerExpression = innerExpression; continue; } if (innerExpression == null) { continue; } outerExpression = Expression.And(outerExpression, innerExpression); } return(outerExpression == null ? result : result.Where(Expression.Lambda <Func <TEntity, bool> >(outerExpression, parameterExpression))); }