コード例 #1
0
 public static IQueryable <T> ApplyFilteringAndOrdering <T>(this IQueryable <T> query, IGridifyQuery?gridifyQuery,
                                                            IGridifyMapper <T>?mapper = null)
 {
     query = query.ApplyFiltering(gridifyQuery, mapper);
     query = query.ApplyOrdering(gridifyQuery, mapper);
     return(query);
 }
コード例 #2
0
    public static bool IsValid <T>(this IGridifyFiltering filtering, IGridifyMapper <T>?mapper = null)
    {
        if (string.IsNullOrWhiteSpace(filtering.Filter))
        {
            return(true);
        }
        try
        {
            var parser     = new Parser(filtering.Filter !, GridifyGlobalConfiguration.CustomOperators.Operators);
            var syntaxTree = parser.Parse();
            if (syntaxTree.Diagnostics.Any())
            {
                return(false);
            }

            var fieldExpressions = syntaxTree.Root.Descendants()
                                   .Where(q => q.Kind is SyntaxKind.FieldExpression)
                                   .Cast <FieldExpressionSyntax>().ToList();

            mapper ??= new GridifyMapper <T>(true);

            if (fieldExpressions.Any(field => !mapper.HasMap(field.FieldToken.Text)))
            {
                return(false);
            }
        }
        catch (Exception)
        {
            return(false);
        }

        return(true);
    }
コード例 #3
0
    /// <summary>
    /// if given mapper was null this function creates default generated mapper
    /// </summary>
    /// <param name="mapper">a <c>GridifyMapper<c /> that can be null</param>
    /// <param name="syntaxTree">optional syntaxTree to Lazy mapping generation</param>
    /// <typeparam name="T">type to set mappings</typeparam>
    /// <returns>return back mapper or new generated mapper if it was null</returns>
    private static IGridifyMapper <T> FixMapper <T>(this IGridifyMapper <T>?mapper, SyntaxTree syntaxTree)
    {
        if (mapper != null)
        {
            return(mapper);
        }

        mapper = new GridifyMapper <T>();
        foreach (var field in syntaxTree.Root.Descendants()
                 .Where(q => q.Kind == SyntaxKind.FieldExpression)
                 .Cast <FieldExpressionSyntax>())
        {
            try
            {
                mapper.AddMap(field.FieldToken.Text);
            }
            catch (Exception)
            {
                if (!mapper.Configuration.IgnoreNotMappedFields)
                {
                    throw new GridifyMapperException($"Property '{field.FieldToken.Text}' not found.");
                }
            }
        }

        return(mapper);
    }
コード例 #4
0
        public static async Task <Paging <T> > GridifyAsync <T>(this IQueryable <T> query, IGridifyQuery gridifyQuery, CancellationToken token,
                                                                IGridifyMapper <T>?mapper = null)
        {
            var(count, queryable) = await query.GridifyQueryableAsync(gridifyQuery, mapper, token);

            return(new Paging <T>(count, await queryable.ToListAsync(token)));
        }
コード例 #5
0
        public static async Task <QueryablePaging <T> > GridifyQueryableAsync <T>(this IQueryable <T> query, IGridifyQuery gridifyQuery,
                                                                                  IGridifyMapper <T>?mapper, CancellationToken token)
        {
            query = query.ApplyFiltering(gridifyQuery, mapper);
            var count = await query.CountAsync(token);

            query = query.ApplyOrdering(gridifyQuery, mapper);
            query = query.ApplyPaging(gridifyQuery);
            return(new QueryablePaging <T>(count, query));
        }
コード例 #6
0
    /// <summary>
    /// adds Ordering to the query
    /// </summary>
    /// <param name="query">the original(target) queryable object</param>
    /// <param name="gridifyOrdering">the configuration to apply ordering</param>
    /// <param name="groupOrder">select group member for ordering</param>
    /// // need to be more specific
    /// <param name="isGroupOrderAscending"></param>
    /// <param name="mapper">this is an optional parameter to apply ordering using a custom mapping configuration</param>
    /// <typeparam name="T">type of target entity</typeparam>
    /// <typeparam name="TKey">type of target property</typeparam>
    /// <returns>returns user query after applying Ordering </returns>
    public static IQueryable <T> ApplyOrdering <T, TKey>(this IQueryable <T> query, IGridifyOrdering?gridifyOrdering,
                                                         Expression <Func <T, TKey> > groupOrder, bool isGroupOrderAscending = true,
                                                         IGridifyMapper <T>?mapper = null)
    {
        if (gridifyOrdering == null)
        {
            return(query);
        }

        if (string.IsNullOrWhiteSpace(gridifyOrdering.OrderBy))
        {
            return(query);
        }

        query = isGroupOrderAscending
         ? query.OrderBy(groupOrder)
         : query.OrderByDescending(groupOrder);

        query = ProcessOrdering(query, gridifyOrdering.OrderBy !, true, mapper);
        return(query);
    }
コード例 #7
0
    public static bool IsValid <T>(this IGridifyOrdering ordering, IGridifyMapper <T>?mapper = null)
    {
        if (string.IsNullOrWhiteSpace(ordering.OrderBy))
        {
            return(true);
        }
        try
        {
            var orders = ParseOrderings(ordering.OrderBy !).ToList();
            mapper ??= new GridifyMapper <T>(true);
            if (orders.Any(order => !mapper.HasMap(order.MemberName)))
            {
                return(false);
            }
        }
        catch (Exception)
        {
            return(false);
        }

        return(true);
    }
コード例 #8
0
 public static IQueryable <T> ApplyFiltering <T>(this IQueryable <T> query, IGridifyFiltering?gridifyFiltering, IGridifyMapper <T>?mapper = null)
 {
     if (gridifyFiltering == null)
     {
         return(query);
     }
     return(string.IsNullOrWhiteSpace(gridifyFiltering.Filter) ? query : ApplyFiltering(query, gridifyFiltering.Filter, mapper));
 }
コード例 #9
0
 /// <summary>
 /// adds Ordering to the query
 /// </summary>
 /// <param name="query">the original(target) queryable object</param>
 /// <param name="orderBy">the ordering fields</param>
 /// <param name="mapper">this is an optional parameter to apply ordering using a custom mapping configuration</param>
 /// <param name="startWithThenBy">
 /// if you already have an ordering with start with ThenBy, new orderings will add on top of
 /// your orders
 /// </param>
 /// <typeparam name="T">type of target entity</typeparam>
 /// <returns>returns user query after applying Ordering </returns>
 public static IQueryable <T> ApplyOrdering <T>(this IQueryable <T> query, string orderBy, IGridifyMapper <T>?mapper = null,
                                                bool startWithThenBy = false)
 {
     return(string.IsNullOrWhiteSpace(orderBy)
      ? query
      : ProcessOrdering(query, orderBy, startWithThenBy, mapper));
 }
コード例 #10
0
    /// <summary>
    /// gets a query or collection,
    /// adds filtering, ordering and paging
    /// loads filtered and sorted data
    /// return pagination ready result
    /// </summary>
    /// <param name="query">the original(target) queryable object</param>
    /// <param name="queryOption">the configuration to apply paging, filtering and ordering</param>
    /// <param name="mapper">this is an optional parameter to apply filtering and ordering using a custom mapping configuration</param>
    /// <typeparam name="T">type of target entity</typeparam>
    /// <returns>returns a loaded <c>Paging<T><c /> after applying filtering, ordering and paging </returns>
    /// <returns></returns>
    public static Paging <T> Gridify <T>(this IQueryable <T> query, Action <IGridifyQuery> queryOption, IGridifyMapper <T>?mapper = null)
    {
        var gridifyQuery = new GridifyQuery();

        queryOption.Invoke(gridifyQuery);
        var(count, queryable) = query.GridifyQueryable(gridifyQuery, mapper);
        return(new Paging <T>(count, queryable.ToList()));
    }
コード例 #11
0
 /// <summary>
 /// gets a query or collection,
 /// adds filtering, ordering and paging
 /// loads filtered and sorted data
 /// return pagination ready result
 /// </summary>
 /// <param name="query">the original(target) queryable object</param>
 /// <param name="gridifyQuery">the configuration to apply paging, filtering and ordering</param>
 /// <param name="mapper">this is an optional parameter to apply filtering and ordering using a custom mapping configuration</param>
 /// <typeparam name="T">type of target entity</typeparam>
 /// <returns>returns a loaded <c>Paging<T><c /> after applying filtering, ordering and paging </returns>
 /// <returns></returns>
 public static Paging <T> Gridify <T>(this IQueryable <T> query, IGridifyQuery?gridifyQuery, IGridifyMapper <T>?mapper = null)
 {
     var(count, queryable) = query.GridifyQueryable(gridifyQuery, mapper);
     return(new Paging <T>(count, queryable.ToList()));
 }
コード例 #12
0
    /// <summary>
    /// gets a query or collection,
    /// adds filtering,
    /// Get totalItems Count
    /// adds ordering and paging
    /// return QueryablePaging with TotalItems and an IQueryable Query
    /// </summary>
    /// <param name="query">the original(target) queryable object</param>
    /// <param name="gridifyQuery">the configuration to apply paging, filtering and ordering</param>
    /// <param name="mapper">this is an optional parameter to apply filtering and ordering using a custom mapping configuration</param>
    /// <typeparam name="T">type of target entity</typeparam>
    /// <returns>returns a <c>QueryablePaging<T><c/> after applying filtering, ordering and paging</returns>
    public static QueryablePaging <T> GridifyQueryable <T>(this IQueryable <T> query, IGridifyQuery?gridifyQuery, IGridifyMapper <T>?mapper = null)
    {
        query = query.ApplyFiltering(gridifyQuery, mapper);
        var count = query.Count();

        query = query.ApplyOrdering(gridifyQuery, mapper);
        query = query.ApplyPaging(gridifyQuery);
        return(new QueryablePaging <T>(count, query));
    }
コード例 #13
0
    public static Expression <Func <T, bool> > CreateQuery <T>(this SyntaxTree syntaxTree, IGridifyMapper <T>?mapper = null)
    {
        mapper = mapper.FixMapper(syntaxTree);
        var exp = ExpressionToQueryConvertor.GenerateQuery(syntaxTree.Root, mapper).Expression;

        if (exp == null)
        {
            throw new GridifyQueryException("Invalid SyntaxTree.");
        }
        return(exp);
    }
コード例 #14
0
    public static IQueryable <object> ApplySelect <T>(this IQueryable <T> query, string props, IGridifyMapper <T>?mapper = null)
    {
        if (string.IsNullOrWhiteSpace(props))
        {
            return((IQueryable <object>)query);
        }

        if (mapper is null)
        {
            mapper = new GridifyMapper <T>(true);
        }

        var exp    = mapper.GetExpression(props);
        var result = query.Select(exp);


        return(result);
    }
コード例 #15
0
    public static IQueryable <T> ApplyFiltering <T>(this IQueryable <T> query, string?filter, IGridifyMapper <T>?mapper = null)
    {
        if (string.IsNullOrWhiteSpace(filter))
        {
            return(query);
        }

        var syntaxTree = SyntaxTree.Parse(filter !, GridifyGlobalConfiguration.CustomOperators.Operators);

        if (syntaxTree.Diagnostics.Any())
        {
            throw new GridifyFilteringException(syntaxTree.Diagnostics.Last());
        }

        mapper = mapper.FixMapper(syntaxTree);

        var(queryExpression, _) = ExpressionToQueryConvertor.GenerateQuery(syntaxTree.Root, mapper);

        query = query.Where(queryExpression);

        return(query);
    }
コード例 #16
0
    public static IEnumerable <Expression <Func <T, object> > > GetOrderingExpressions <T>(this IGridifyOrdering gridifyOrdering,
                                                                                           IGridifyMapper <T>?mapper = null)
    {
        if (string.IsNullOrWhiteSpace(gridifyOrdering.OrderBy))
        {
            throw new GridifyQueryException("OrderBy is not defined or not Found");
        }


        var members = ParseOrderings(gridifyOrdering.OrderBy !).Select(q => q.MemberName).ToList();

        if (mapper is null)
        {
            foreach (var member in members)
            {
                Expression <Func <T, object> >?exp = null;
                try
                {
                    exp = GridifyMapper <T> .CreateExpression(member);
                }
                catch (Exception)
                {
                    // skip if there is no mappings available
                }

                if (exp != null)
                {
                    yield return(exp);
                }
            }
        }
        else
        {
            foreach (var member in members.Where(mapper.HasMap))
            {
                yield return(mapper.GetExpression(member) !);
            }
        }
    }
コード例 #17
0
        private static Expression <Func <T, bool> > GetExpressionFromCondition <T> (string condition, IGridifyQuery gridifyQuery, IGridifyMapper <T> mapper)
        {
            try
            {
                string[] op   = { "==", "!=", "=*", "!*", ">>", "<<", ">=", "<=" };
                var      maps = ParseFilter(condition, op);

                if (!maps.HasValue)
                {
                    return(null);
                }

                var gMap = mapper.GetGMap(maps.Value.Left);
                Expression <Func <T, object> > exp = gMap.To;
                var body = exp.Body;

                // Remove the boxing for value types
                if (body.NodeType == ExpressionType.Convert)
                {
                    body = ((UnaryExpression)body).Operand;
                }

                object value = maps.Value.Right;

                // execute user custom Convertor
                if (gMap.Convertor != null)
                {
                    value = gMap.Convertor.Invoke(maps.Value.Right);
                }


                if (value != null && body.Type != value.GetType())
                {
                    try
                    {
                        // handle broken guids,  github issue #2
                        if (body.Type == typeof(Guid) && !Guid.TryParse(value.ToString(), out _))
                        {
                            value = Guid.NewGuid();
                        }

                        var converter = TypeDescriptor.GetConverter(body.Type);
                        value = converter.ConvertFromString(value.ToString());
                    }
                    catch (System.FormatException)
                    {
                        // return no records in case of any exception in formating
                        return(q => false);
                    }
                }
                Expression be             = null;
                var        ContainsMethod = typeof(string).GetMethod("Contains", new [] { typeof(string) });
                switch (maps.Value.Operation)
                {
                case "==":
                    be = Expression.Equal(body, Expression.Constant(value, body.Type));
                    break;

                case "!=":
                    be = Expression.NotEqual(body, Expression.Constant(value, body.Type));
                    break;

                case ">>":
                    be = Expression.GreaterThan(body, Expression.Constant(value, body.Type));
                    break;

                case "<<":
                    be = Expression.LessThan(body, Expression.Constant(value, body.Type));
                    break;

                case ">=":
                    be = Expression.GreaterThanOrEqual(body, Expression.Constant(value, body.Type));
                    break;

                case "<=":
                    be = Expression.LessThanOrEqual(body, Expression.Constant(value, body.Type));
                    break;

                case "=*":
                    be = Expression.Call(body, ContainsMethod, Expression.Constant(value, body.Type));
                    break;

                case "!*":
                    be = Expression.Not(Expression.Call(body, ContainsMethod, Expression.Constant(value, body.Type)));
                    break;

                default:
                    return(null);
                }
                return(Expression.Lambda <Func <T, bool> > (be, exp.Parameters));
            }
            catch (Exception)
            {
                return(null);
            }
        }
コード例 #18
0
        public async static Task <Paging <T> > GridifyAsync <T> (this IQueryable <T> query, IGridifyQuery gridifyQuery, IGridifyMapper <T> mapper = null)
        {
            mapper = mapper.FixMapper();
            var res = await query.GridifyQueryableAsync(gridifyQuery, mapper);

            return(new Paging <T> ()
            {
                Items = await res.Query.ToListAsync(), TotalItems = res.TotalItems
            });
        }
コード例 #19
0
    internal static Expression <Func <T, object> > GetOrderExpression <T>(ParsedOrdering order, IGridifyMapper <T> mapper)
    {
        var exp = mapper.GetExpression(order.MemberName);

        switch (order.OrderingType)
        {
        case OrderingType.Normal:
            return(exp);

        case OrderingType.NullCheck:
        case OrderingType.NotNullCheck:
        default:
        {
            // member should be nullable
            if (exp.Body is not UnaryExpression unary || Nullable.GetUnderlyingType(unary.Operand.Type) == null)
            {
                throw new GridifyOrderingException($"'{order.MemberName}' is not nullable type");
            }

            var prop     = Expression.Property(exp.Parameters[0], order.MemberName);
            var hasValue = Expression.PropertyOrField(prop, "HasValue");

            switch (order.OrderingType)
            {
            case OrderingType.NullCheck:
            {
                var boxedExpression = Expression.Convert(hasValue, typeof(object));
                return(Expression.Lambda <Func <T, object> >(boxedExpression, exp.Parameters));
            }

            case OrderingType.NotNullCheck:
            {
                var notHasValue     = Expression.Not(hasValue);
                var boxedExpression = Expression.Convert(notHasValue, typeof(object));
                return(Expression.Lambda <Func <T, object> >(boxedExpression, exp.Parameters));
            }

            // should never reach here
            case OrderingType.Normal:
                return(exp);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        }
    }
コード例 #20
0
    internal static IQueryable <T> ProcessOrdering <T>(IQueryable <T> query, string orderings, bool startWithThenBy, IGridifyMapper <T>?mapper)
    {
        var isFirst = !startWithThenBy;

        var orders = ParseOrderings(orderings).ToList();

        // build the mapper if it is null
        if (mapper is null)
        {
            mapper = new GridifyMapper <T>();
            foreach (var order in orders)
            {
                try
                {
                    mapper.AddMap(order.MemberName);
                }
                catch (Exception)
                {
                    if (!mapper.Configuration.IgnoreNotMappedFields)
                    {
                        throw new GridifyMapperException($"Mapping '{order.MemberName}' not found");
                    }
                }
            }
        }

        foreach (var order in orders)
        {
            if (!mapper.HasMap(order.MemberName))
            {
                // skip if there is no mappings available
                if (mapper.Configuration.IgnoreNotMappedFields)
                {
                    continue;
                }

                throw new GridifyMapperException($"Mapping '{order.MemberName}' not found");
            }

            if (isFirst)
            {
                query   = query.OrderByMember(GetOrderExpression(order, mapper), order.IsAscending);
                isFirst = false;
            }
            else
            {
                query = query.ThenByMember(GetOrderExpression(order, mapper), order.IsAscending);
            }
        }

        return(query);
    }
コード例 #21
0
    public static Expression <Func <T, bool> > GetFilteringExpression <T>(this IGridifyFiltering gridifyFiltering, IGridifyMapper <T>?mapper = null)
    {
        if (string.IsNullOrWhiteSpace(gridifyFiltering.Filter))
        {
            throw new GridifyQueryException("Filter is not defined");
        }

        var syntaxTree = SyntaxTree.Parse(gridifyFiltering.Filter !, GridifyGlobalConfiguration.CustomOperators.Operators);

        if (syntaxTree.Diagnostics.Any())
        {
            throw new GridifyFilteringException(syntaxTree.Diagnostics.Last() !);
        }

        mapper = mapper.FixMapper(syntaxTree);
        var(queryExpression, _) = ExpressionToQueryConvertor.GenerateQuery(syntaxTree.Root, mapper);
        if (queryExpression == null)
        {
            throw new GridifyQueryException("Can not create expression with current data");
        }
        return(queryExpression);
    }
コード例 #22
0
 /// <summary>
 /// Validates Filter and/or OrderBy with Mappings
 /// </summary>
 /// <param name="gridifyQuery">gridify query with (Filter or OrderBy) </param>
 /// <param name="mapper">the gridify mapper that you want to use with, this is optional</param>
 /// <typeparam name="T"></typeparam>
 /// <returns></returns>
 public static bool IsValid <T>(this IGridifyQuery gridifyQuery, IGridifyMapper <T>?mapper = null)
 {
     return(((IGridifyFiltering)gridifyQuery).IsValid(mapper) &&
            ((IGridifyOrdering)gridifyQuery).IsValid(mapper));
 }
コード例 #23
0
        public async static Task <QueryablePaging <T> > GridifyQueryableAsync <T> (this IQueryable <T> query, IGridifyQuery gridifyQuery, IGridifyMapper <T> mapper)
        {
            query = query.ApplyFiltering(gridifyQuery, mapper);
            var count = await query.CountAsync();

            query = query.ApplyOrdering(gridifyQuery, mapper);
            query = query.ApplyPaging(gridifyQuery);
            return(new QueryablePaging <T> ()
            {
                TotalItems = count, Query = query
            });
        }
コード例 #24
0
 private static Expression <Func <T, bool> > GetExpressionFromInternalConditions <T> (IGridifyQuery gridifyQuery, IGridifyMapper <T> mapper, List <(string condition, bool IsAnd)> conditions)