Esempio n. 1
0
        /// <summary>
        /// Binds a 'substring' function to create a LINQ <see cref="Expression"/>.
        /// </summary>
        /// <param name="node">The query node to bind.</param>
        /// <param name="context">The query binder context.</param>
        /// <returns>The LINQ <see cref="Expression"/> created.</returns>
        protected virtual Expression BindSubstring(SingleValueFunctionCallNode node, QueryBinderContext context)
        {
            CheckArgumentNull(node, context, "substring");

            Expression[] arguments = BindArguments(node.Parameters, context);
            if (arguments[0].Type != typeof(string))
            {
                throw new ODataException(Error.Format(SRResources.FunctionNotSupportedOnEnum, node.Name));
            }

            ODataQuerySettings querySettings = context.QuerySettings;

            Expression functionCall;

            if (arguments.Length == 2)
            {
                Contract.Assert(ExpressionBinderHelper.IsInteger(arguments[1].Type));

                // When null propagation is allowed, we use a safe version of String.Substring(int).
                // But for providers that would not recognize custom expressions like this, we map
                // directly to String.Substring(int)
                if (context.QuerySettings.HandleNullPropagation == HandleNullPropagationOption.True)
                {
                    // Safe function is static and takes string "this" as first argument
                    functionCall = ExpressionBinderHelper.MakeFunctionCall(ClrCanonicalFunctions.SubstringStartNoThrow, querySettings, arguments);
                }
                else
                {
                    functionCall = ExpressionBinderHelper.MakeFunctionCall(ClrCanonicalFunctions.SubstringStart, querySettings, arguments);
                }
            }
            else
            {
                // arguments.Length == 3 implies String.Substring(int, int)
                Contract.Assert(arguments.Length == 3 && ExpressionBinderHelper.IsInteger(arguments[1].Type) && ExpressionBinderHelper.IsInteger(arguments[2].Type));

                // When null propagation is allowed, we use a safe version of String.Substring(int, int).
                // But for providers that would not recognize custom expressions like this, we map
                // directly to String.Substring(int, int)
                if (querySettings.HandleNullPropagation == HandleNullPropagationOption.True)
                {
                    // Safe function is static and takes string "this" as first argument
                    functionCall = ExpressionBinderHelper.MakeFunctionCall(ClrCanonicalFunctions.SubstringStartAndLengthNoThrow, querySettings, arguments);
                }
                else
                {
                    functionCall = ExpressionBinderHelper.MakeFunctionCall(ClrCanonicalFunctions.SubstringStartAndLength, querySettings, arguments);
                }
            }

            return(functionCall);
        }