コード例 #1
0
            public static Expression BuildOrderExpression(
                Expression queryExpression,
                OrderingFields orderingFields)
            {
                queryExpression = GetOrderBy(queryExpression, orderingFields.Fields[0]);

                foreach (OrderingField field in orderingFields.Fields.Skip(1))
                {
                    queryExpression = GetThenBy(queryExpression, field);
                }

                return(queryExpression);
            }
コード例 #2
0
        public IQueryable <OrderedItem> BuildAfterQuery(
            IQueryable <TDbObject> query,
            Expression <Func <TDbObject, TOrder> > orderBy,
            Expression <Func <TOrder, TOrder, bool> > filter,
            Expression <Func <TDbObject, TResult> > select,
            Cursor after)
        {
            MemberInitExpression orderedItemInit = Expression.MemberInit(
                Expression.New(typeof(OrderedItem)),
                Expression.Bind(OrderMember, ParameterReplacer.RepalceParameter(new SortDirectionRemoverVisitor(orderBy.Body).Expression)),
                Expression.Bind(ValueMember, ParameterReplacer.RepalceParameter(select.Body)));

            Expression queryExpression = query.Expression;

            OrderingFields orderingFields = OrderRequestBuilder.GetOrdering(orderBy);

            if (_cursorFormatter.HasValue(after))
            {
                TOrder order = _cursorFormatter.ParseAs <TOrder>(after);

                Expression filterBody =
                    filter != null
                    ? FilterBuilder.RemapFilter(orderedItemInit, filter, order)
                    : FilterBuilder.BuildAutoFilter(orderedItemInit, orderingFields, order);

                // add where filtration
                queryExpression = Expression.Call(
                    typeof(Queryable),
                    nameof(Queryable.Where),
                    new System.Type[] { typeof(TDbObject) },
                    queryExpression,
                    Expression.Lambda <Func <TDbObject, bool> >(filterBody, DbItem));
            }

            // add passed order
            queryExpression = OrderRequestBuilder.BuildOrderExpression(queryExpression, orderingFields);

            // extend selection and add order fields
            queryExpression = Expression.Call(
                typeof(Queryable),
                nameof(Queryable.Select),
                new System.Type[] { typeof(TDbObject), typeof(OrderedItem) },
                queryExpression,
                Expression.Lambda <Func <TDbObject, OrderedItem> >(orderedItemInit, DbItem));

            return(query.Provider.CreateQuery <OrderedItem>(queryExpression));
        }
            public static Expression BuildAutoFilter(
                Expression mappingExpression,
                OrderingFields orderingFields,
                TOrder after)
            {
                var filters = new List <FilterValue>(capacity: orderingFields.Fields.Count);

                foreach (OrderingField field in orderingFields.Fields)
                {
                    var value = orderingFields.IsDirect ? after : GetValue(after, field);

                    filters.Add(new FilterValue
                    {
                        Expression = field.Expression,
                        Value      = Expression.Constant(value),
                        IsLower    = field.IsDescending,
                    });
                }

                Expression filter = null;

                for (var current = 0; current < filters.Count; current++)
                {
                    FilterValue currentValue  = filters[current];
                    Expression  currentFilter = null;

                    for (var prev = 0; prev < current; prev++)
                    {
                        FilterValue prevValue = filters[prev];

                        Expression equal = Expression.Equal(prevValue.Expression, prevValue.Value);
                        currentFilter = currentFilter != null?Expression.AndAlso(currentFilter, equal) : equal;
                    }

                    Expression compare = GreateCompareExpression(currentValue);
                    currentFilter = currentFilter != null?Expression.AndAlso(currentFilter, compare) : compare;

                    filter = filter != null?Expression.OrElse(filter, currentFilter) : currentFilter;
                }

                return(ParameterReplacer.RepalceParameter(filter));
            }
コード例 #4
0
            public static OrderingFields GetOrdering(Expression <Func <TDbObject, TOrder> > orderBy)
            {
                var result = new OrderingFields
                {
                    OrderParameter = orderBy.Parameters[0]
                };

                result.Fields =
                    (from item in new OrderingMappingVisitor(orderBy).GetMappingList()
                     where item.Member.DeclaringType == typeof(TOrder)
                     let property = (PropertyInfo)item.Member
                                    let sortDirection = new SortDirectionVisitor(item.Expression)
                                                        select new OrderingField
                {
                    Type = property.PropertyType,
                    Expression = sortDirection.Expression,
                    IsDescending = sortDirection.IsDescending,
                    Property = property,
                }).ToArray();

                // if order is simple direct field access like (item => item.id)
                if (result.Fields.Count == 0)
                {
                    var sortDirection = new SortDirectionVisitor(orderBy.Body);
                    result.Fields = new[]
                    {
                        new OrderingField
                        {
                            Type         = typeof(TOrder),
                            Expression   = sortDirection.Expression,
                            IsDescending = sortDirection.IsDescending,
                        }
                    };
                    result.IsDirect = true;
                }

                return(result);
            }