Example #1
0
        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);
        }
Example #2
0
        /// <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);
                }
            }
        }
Example #3
0
        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);
        }
Example #4
0
        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)));
        }