示例#1
0
        public FilterParameter[] ParseFilters(Type type, QueryParameter[] queryParameters)
        {
            var filters = new List <FilterParameter>();

            var properties = _propertyCache.GetProperties(type);

            foreach (var propertyInfo in properties)
            {
                var filter = queryParameters.FirstOrDefault(q =>
                                                            string.Equals(q.Key, propertyInfo.Name, StringComparison.OrdinalIgnoreCase));

                if (filter != null)
                {
                    var opStr = queryParameters.FirstOrDefault(q =>
                                                               string.Equals($"{filter.Key}_op", q.Key, StringComparison.OrdinalIgnoreCase));

                    var op = Op.Equals;
                    if (opStr != null)
                    {
                        op = ParseOperator(opStr.Value);
                    }

                    filters.Add(new FilterParameter(filter.Key, op, filter.Value, propertyInfo));
                }

                var nullFilter = queryParameters.FirstOrDefault(q =>
                                                                q.Key.Equals($"{propertyInfo.Name}_op", StringComparison.OrdinalIgnoreCase) &&
                                                                (q.Value.Equals("isnull", StringComparison.OrdinalIgnoreCase) ||
                                                                 q.Value.Equals("notnull", StringComparison.OrdinalIgnoreCase)));

                if (nullFilter != null)
                {
                    filters.Add(new FilterParameter(propertyInfo.Name, ParseOperator(nullFilter.Value),
                                                    nullFilter.Value, propertyInfo));
                }
            }

            return(filters.ToArray());
        }
示例#2
0
        public async Task <QueryResult <TEntity> > ApplyAsync <TEntity>(IQueryable <TEntity> entities, FilterParameter[] filters,
                                                                        SortParameter[] sorts, PaginationParameter pagination,
                                                                        CancellationToken cancellationToken)
        {
            if (filters != null && filters.Length > 0)
            {
                var        propreties          = _propertyCache.GetProperties <TEntity>();
                var        parameterExpression = Expression.Parameter(typeof(TEntity), "e");
                Expression outerExpression     = null;
                foreach (var filter in filters)
                {
                    var property =
                        propreties.FirstOrDefault(q =>
                                                  string.Equals(q.Name, filter.FieldName, StringComparison.OrdinalIgnoreCase));

                    if (property == null)
                    {
                        throw new ArgumentException($"Property for Filter.Field({filter.FieldName}) not found.");
                    }

                    var converter = TypeDescriptor.GetConverter(property.PropertyType);

                    dynamic propertyValue = Expression.PropertyOrField(parameterExpression, property.Name);

                    Expression innerExpression = null;
                    if (filter.Op == Op.In)
                    {
                        foreach (var value in filter.Values)
                        {
                            dynamic constantVal = GetConstantVal <TEntity>(converter, value, property);

                            Expression filterValue = Expression.Constant(constantVal, property.PropertyType);

                            var filterExpression = GetBinaryExpression(Op.Equals, filterValue, propertyValue);

                            innerExpression = innerExpression == null
                                ? filterExpression
                                : Expression.OrElse(innerExpression, filterExpression);
                        }
                    }
                    else if (filter.Op == Op.Between)
                    {
                        dynamic    leftConstantVal = GetConstantVal <TEntity>(converter, filter.Values[0], property);
                        Expression leftFilterValue = Expression.Constant(leftConstantVal, property.PropertyType);

                        dynamic    rightConstantVal = GetConstantVal <TEntity>(converter, filter.Values[1], property);
                        Expression rightFilterValue = Expression.Constant(rightConstantVal, property.PropertyType);

                        innerExpression = Expression.And(
                            GetBinaryExpression(Op.GreaterThanOrEqualTo, leftFilterValue, propertyValue),
                            GetBinaryExpression(Op.LessThanOrEqualTo, rightFilterValue, propertyValue)
                            );
                    }
                    else if (filter.Op == Op.IsNull || filter.Op == Op.NotNull)
                    {
                        innerExpression = GetBinaryExpression(filter.Op, null, propertyValue);
                    }
                    else
                    {
                        dynamic    constantVal = GetConstantVal <TEntity>(converter, filter.Values[0], property);
                        Expression filterValue = Expression.Constant(constantVal, property.PropertyType);
                        innerExpression = GetBinaryExpression(filter.Op, filterValue, propertyValue);
                    }

                    if (outerExpression == null)
                    {
                        outerExpression = innerExpression;
                    }
                    else
                    {
                        outerExpression = Expression.AndAlso(outerExpression, innerExpression);
                    }
                }

                entities = outerExpression == null
                    ? entities
                    : entities.Where(Expression.Lambda <Func <TEntity, bool> >(outerExpression, parameterExpression));
            }

            if (sorts != null && sorts.Length > 0)
            {
                var useThenBy = false;
                foreach (var sortParameter in sorts)
                {
                    entities  = OrderByDynamic(entities, sortParameter.Field, sortParameter.Desc, useThenBy);
                    useThenBy = true;
                }
            }

            if (pagination != null)
            {
                var totalCount = entities.Count();
                var result     = await entities.Skip((pagination.PageNumber - 1) *pagination.PageSize)
                                 .Take(pagination.PageSize).ToArrayAsync(cancellationToken);

                return(new QueryResult <TEntity>
                {
                    Data = result,
                    TotalCount = totalCount,
                    PageSize = pagination.PageSize,
                    PageNumber = pagination.PageNumber
                });
            }

            var data = await entities.ToArrayAsync(cancellationToken);

            return(new QueryResult <TEntity>
            {
                Data = data,
                TotalCount = data.Length
            });
        }