/// <summary>
        /// Apply orderby to the given resouce expression
        /// </summary>
        /// <param name="rootExpression"></param>
        /// <param name="entityInstanceType"></param>
        /// <param name="uriParser"></param>
        /// <param name="orderByClause"></param>
        /// <returns></returns>
        public static Expression ApplyOrderBy(this Expression rootExpression, Type entityInstanceType, ODataUriParser uriParser, OrderByClause orderByClause)
        {
            ParameterExpression        parameter = Expression.Parameter(entityInstanceType, "it");
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser = uriParser,
            };

            Expression orderByNodeExpression = nodeToExpressionTranslator.TranslateNode(orderByClause.Expression);

            var keyType = EdmClrTypeUtils.GetInstanceType(orderByClause.Expression.TypeReference);

            if (orderByClause.Expression.TypeReference.IsNullable && keyType.IsValueType)
            {
                keyType = typeof(Nullable <>).MakeGenericType(keyType);
            }

            var method = orderByClause.Direction == OrderByDirection.Ascending ? "OrderBy" : "OrderByDescending";
            //OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
            var expression = Expression.Call(
                typeof(Enumerable),
                method,
                new Type[] { entityInstanceType, keyType },
                rootExpression,
                Expression.Lambda(orderByNodeExpression, parameter)) as Expression;
            var thenBy = orderByClause.ThenBy;

            while (null != thenBy)
            {
                expression = expression.ApplyThenBy(entityInstanceType, uriParser, thenBy);
                thenBy     = thenBy.ThenBy;
            }
            return(expression);
        }
        /// <summary>
        /// Apply filter to the given resouce expression
        /// </summary>
        /// <param name="rootExpression"></param>
        /// <param name="entityInstanceType"></param>
        /// <param name="uriParser"></param>
        /// <param name="filterClause"></param>
        /// <returns></returns>
        public static Expression ApplyFilter(this Expression rootExpression, Type entityInstanceType, ODataUriParser uriParser, FilterClause filterClause)
        {
            ParameterExpression        parameter = Expression.Parameter(entityInstanceType, "it");
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser = uriParser,
            };
            Expression filterNodeExpression = nodeToExpressionTranslator.TranslateNode(filterClause.Expression);

            // IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
            // translate to rootExpression.Where(filterNodeExpression)
            return(Expression.Call(
                       typeof(Enumerable),
                       "Where",
                       new Type[] { entityInstanceType },
                       rootExpression,
                       Expression.Lambda(filterNodeExpression, parameter)));
        }
Beispiel #3
0
        /// <summary>
        /// Visit an AnyNode
        /// </summary>
        /// <param name="nodeIn">The node to visit</param>
        /// <returns>The translated expression</returns>
        public override Expression Visit(AnyNode nodeIn)
        {
            var instanceType = EdmClrTypeUtils.GetInstanceType(nodeIn.RangeVariables[0].TypeReference);
            ParameterExpression        parameter = Expression.Parameter(instanceType, nodeIn.RangeVariables[0].Name);
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser  = this.UriParser,
                DataSource = this.DataSource,
            };
            Expression conditionExpression = nodeToExpressionTranslator.TranslateNode(nodeIn.Body);
            Expression rootExpression      = this.TranslateNode(nodeIn.Source);

            return(Expression.Call(
                       typeof(Enumerable),
                       "Any",
                       new Type[] { instanceType },
                       rootExpression,
                       Expression.Lambda(conditionExpression, parameter)));
        }
        /// <summary>
        /// Apply thenOrderBy to the given resouce expression
        /// </summary>
        /// <param name="rootExpression"></param>
        /// <param name="entityInstanceType"></param>
        /// <param name="uriParser"></param>
        /// <param name="thenBy"></param>
        /// <returns></returns>
        public static Expression ApplyThenBy(this Expression rootExpression, Type entityInstanceType, ODataUriParser uriParser, OrderByClause thenBy)
        {
            ParameterExpression        parameter = Expression.Parameter(entityInstanceType, "it");
            NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
            {
                ImplicitVariableParameterExpression = parameter,
                UriParser = uriParser,
            };
            Expression orderByNodeExpression = nodeToExpressionTranslator.TranslateNode(thenBy.Expression);

            var keyType = EdmClrTypeUtils.GetInstanceType(thenBy.Expression.TypeReference);
            var method  = thenBy.Direction == OrderByDirection.Ascending ? "ThenBy" : "ThenByDescending";

            //ThenBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector)
            return(Expression.Call(
                       typeof(Enumerable),
                       method,
                       new Type[] { entityInstanceType, keyType },
                       rootExpression,
                       Expression.Lambda(orderByNodeExpression, parameter)));
        }
Beispiel #5
0
        /// <summary>
        /// Translate OperationSegment to linq expression.
        /// </summary>
        /// <param name="segment">The OperationSegment</param>
        /// <returns>The linq expression</returns>
        public override Expression Translate(OperationSegment segment)
        {
            IEdmOperation operation = segment.Operations.First();

            List <Expression> arguments = new List <Expression>();

            if (operation.IsBound)
            {
                arguments.Add(this.ResultExpression);
            }
            if (operation is IEdmFunction)
            {
                NodeToExpressionTranslator nodeToExpressionTranslator = new NodeToExpressionTranslator()
                {
                    UriParser  = this.queryContext.UriParser,
                    DataSource = this.dataSource,
                };

                arguments.AddRange(segment.Parameters.Select(p => nodeToExpressionTranslator.TranslateNode((QueryNode)p.Value)));
                var operationProvider = this.dataSource.OperationProvider;
                operationProvider.QueryContext = this.queryContext;
                this.ResultExpression          = Expression.Call(Expression.Constant(operationProvider), operation.Name, new Type[] { }, arguments.ToArray());
            }
            else if (operation is IEdmAction)
            {
                arguments.AddRange(this.ActionInvokeParameters);
                var operationProvider = this.dataSource.OperationProvider;
                operationProvider.QueryContext = this.queryContext;
                this.ResultExpression          = Expression.Call(Expression.Constant(operationProvider), operation.Name, new Type[] { }, arguments.ToArray());
            }
            else
            {
                throw new NotImplementedException("Unsupported operation type.");
            }

            this.LastProcessedSegment = segment;
            return(this.ResultExpression);
        }