コード例 #1
0
ファイル: ExpressionUtils.cs プロジェクト: zhonli/odata.net
        /// <summary>Replaced the type of input parameter with the given <paramref name="targetType"/></summary>
        /// <param name="input">Input lambda expression.</param>
        /// <param name="targetType">Type of the new parameter that will be replaced.</param>
        /// <returns>New lambda expression with parameter of new type.</returns>
        private static LambdaExpression ReplaceParameterTypeForLambda(LambdaExpression input, Type targetType)
        {
            Debug.Assert(input.Parameters.Count == 1, "Assuming a single parameter for input lambda expression in this function.");

            ParameterExpression p = Expression.Parameter(targetType, input.Parameters[0].Name);

            return(Expression.Lambda(
                       ParameterReplacerVisitor.Replace(input.Body, input.Parameters[0], p),
                       p));
        }
コード例 #2
0
        /// <summary>Composes all query interceptors into a single expression.</summary>
        /// <param name="serviceInstance">Web service instance.</param>
        /// <param name="container">Container for which interceptors should run.</param>
        /// <returns>An expression the filter for query interceptors, possibly null.</returns>
        internal static Expression ComposeQueryInterceptors(object serviceInstance, ResourceSetWrapper container)
        {
            Debug.Assert(container != null, "container != null");
            MethodInfo[] methods = container.QueryInterceptors;
            if (methods == null || methods.Length == 0)
            {
                return(null);
            }

            LambdaExpression filter = null;

            for (int i = 0; i < methods.Length; i++)
            {
                Expression predicate;
                try
                {
                    predicate = (Expression)methods[i].Invoke(serviceInstance, WebUtil.EmptyObjectArray);
                }
                catch (TargetInvocationException tie)
                {
                    ErrorHandler.HandleTargetInvocationException(tie);
                    throw;
                }

                if (predicate == null)
                {
                    throw new InvalidOperationException(Strings.DataService_AuthorizationReturnedNullQuery(methods[i].Name, methods[i].DeclaringType.FullName));
                }

                // predicate is LambdaExpression -- otherwise signature check missed something and following cast would throw
                LambdaExpression lambdaPredicate = ((LambdaExpression)predicate);

                if (filter == null)
                {
                    filter = lambdaPredicate;
                }
                else
                {
                    ParameterExpression parameter         = filter.Parameters[0];
                    Expression          adjustedPredicate = ParameterReplacerVisitor.Replace(
                        lambdaPredicate.Body,             // expression
                        lambdaPredicate.Parameters[0],    // oldParameter
                        parameter);                       // newParameter
                    filter = Expression.Lambda(Expression.And(filter.Body, adjustedPredicate), parameter);
                }
            }

            return(filter);
        }
コード例 #3
0
        /// <summary>Makes the expression that is used as a filter corresponding to skip token.</summary>
        /// <param name="topLevelOrderingInfo">Ordering expression.</param>
        /// <param name="skipToken">The provided skip token.</param>
        /// <param name="parameterType">The parameter type of the lambda.</param>
        /// <returns>LambdaExpression corresponding to the skip token filter.</returns>
        internal LambdaExpression BuildSkipTokenFilter(OrderingInfo topLevelOrderingInfo, IList <object> skipToken, Type parameterType)
        {
            ParameterExpression element       = Expression.Parameter(parameterType, "element");
            Expression          lastCondition = Expression.Constant(true, typeof(bool));
            Expression          lastMatch     = Expression.Constant(false, typeof(bool));

            foreach (var v in WebUtil.Zip(topLevelOrderingInfo.OrderingExpressions, skipToken, (x, y) => new { Order = x, Value = y }))
            {
                BinaryOperatorKind comparisonExp = v.Order.IsAscending ? BinaryOperatorKind.GreaterThan : BinaryOperatorKind.LessThan;

                Expression fixedLambda = ParameterReplacerVisitor.Replace(
                    ((LambdaExpression)v.Order.Expression).Body,
                    ((LambdaExpression)v.Order.Expression).Parameters[0],
                    element);

                // TODO: this will be an EnumNode if $skiptoken contains enum constant.
                ConstantNode node;
                var          lexer   = new ExpressionLexer((string)v.Value);
                bool         success = TokenToQueryNodeTranslator.TryCreateLiteral(lexer.CurrentToken, out node);
                Debug.Assert(success, "Was not a literal");

                node = this.EnsureCorrectTypeAndPrecisionForLFDM(node, fixedLambda.Type);
                Expression right      = this.nodeToExpressionTranslator.TranslateNode(node);
                Expression comparison = ExpressionGenerator.GenerateLogicalAnd(
                    lastCondition,
                    this.GenerateNullAwareComparison(fixedLambda, right, comparisonExp));

                lastMatch = ExpressionGenerator.GenerateLogicalOr(lastMatch, comparison);

                lastCondition = ExpressionGenerator.GenerateLogicalAnd(
                    lastCondition,
                    this.GenerateComparisonExpression(fixedLambda, right, BinaryOperatorKind.Equal));
            }

            lastMatch = ExpressionUtils.EnsurePredicateExpressionIsBoolean(lastMatch);

            Debug.Assert(lastMatch.Type == typeof(bool), "Skip token should generate boolean expression.");

            return(Expression.Lambda(lastMatch, element));
        }
コード例 #4
0
ファイル: ExpressionUtils.cs プロジェクト: zhonli/odata.net
        /// <summary>
        /// Composes a property navigation with the appropriate filter lamba, as appropriate.
        /// </summary>
        /// <param name="expression">Member access expression to compose.</param>
        /// <param name="filterLambda">Lambda expression used for the filter.</param>
        /// <param name="propagateNull">Whether null propagation is required on the <paramref name="expression"/>.</param>
        /// <param name="isSingleResult">Whether <paramref name="expression"/> represent a single resource navigation.</param>
        /// <returns>The composed expression.</returns>
        internal static Expression ComposePropertyNavigation(
            Expression expression,
            LambdaExpression filterLambda,
            bool propagateNull,
            bool isSingleResult)
        {
            Debug.Assert(expression != null, "expression != null");
            Debug.Assert(filterLambda != null, "filterLambda != null");

            Expression nullConstant = NullLiteral;

            if (isSingleResult)
            {
                Expression fixedFilter = ParameterReplacerVisitor.Replace(
                    filterLambda.Body,
                    filterLambda.Parameters[0],
                    expression);

                Expression test = propagateNull
                                      ? Expression.AndAlso(Expression.NotEqual(expression, nullConstant), fixedFilter)
                                      : fixedFilter;

                Expression conditionTrue  = expression;
                Expression conditionFalse = Expression.Constant(null, conditionTrue.Type);
                return(Expression.Condition(test, conditionTrue, conditionFalse));
            }

            Type       elementType      = filterLambda.Parameters[0].Type;
            Expression filterExpression = expression.EnumerableWhere(filterLambda);

            if (propagateNull)
            {
                Expression test    = Expression.Equal(expression, nullConstant);
                Expression falseIf = filterExpression;
                Expression trueIf  = EnumerableEmpty(elementType);
                return(Expression.Condition(test, trueIf, falseIf, trueIf.Type));
            }

            return(filterExpression);
        }