コード例 #1
0
        public static OpenTypeMethodsImplementation GetImplementation(OpenTypeMethodsImplementations type, bool lazyEvaluation)
        {
            OpenTypeMethodsImplementation impl = null;

            switch (type)
            {
            case OpenTypeMethodsImplementations.Default:
                impl = new DefaultOpenTypeMethodsImplementation();
                break;

            case OpenTypeMethodsImplementations.Realistic:
                impl = new RealisticOpenTypeMethodsImplementation();
                break;

            case OpenTypeMethodsImplementations.Tolerant:
                impl = new TolerantOpenTypeMethodsImplementation();
                break;

            default:
                return(null);
            }

            impl.UseLazyBooleanEvaluation = lazyEvaluation;
            return(impl);
        }
コード例 #2
0
        /// <summary>
        /// Visits a method call expression
        /// </summary>
        /// <param name="m">The method call expression</param>
        /// <returns>A new expression after the parameter is visited</returns>
        internal override Expression VisitMethodCall(MethodCallExpression m)
        {
            MethodInfo method = m.Method;

            if (method.ReflectedType == typeof(DataServiceProviderMethods))
            {
                if (DSPMethodsImplementation.ShouldReplaceMethod(method))
                {
                    return(DSPMethodsImplementation.ConvertMethodCall(method, this.VisitExpressionList(m.Arguments)));
                }
                else
                {
                    return(base.VisitMethodCall(m));
                }
            }
            else if (method.ReflectedType == typeof(OpenTypeMethods))
            {
                if (OpenTypeMethodsImplementation.UseLazyBooleanEvaluation)
                {
                    Expression          left  = this.Visit(m.Arguments[0]);
                    Expression          right = this.Visit(m.Arguments[1]);
                    ParameterExpression param = Expression.Parameter(typeof(object), "leftSideLazyEvaluator");
                    if (method.Name.StartsWith("And") || method.Name.StartsWith("Or"))
                    {
                        bool lazyValue = method.Name.StartsWith("And");

                        // if the left-hand side evaluates to a boolean constant that allows lazy evaluation,
                        // then do not evaluate the right hand side
                        right = Expression.Condition(
                            Expression.And(
                                Expression.TypeIs(param, typeof(bool)),
                                Expression.Equal(Expression.Convert(param, typeof(bool)), Expression.Constant(!lazyValue))),
                            Expression.Constant(false, typeof(object)),
                            right);
                    }
                    Expression call = OpenTypeMethodsImplementation.ConvertMethodCall(method, param, right);
                    return(Expression.Invoke(Expression.Lambda(call, param), left));
                }
                else
                {
                    return(OpenTypeMethodsImplementation.ConvertMethodCall(method, this.VisitExpressionList(m.Arguments)));
                }
            }
            else if (method.ReflectedType == typeof(Queryable))
            {
                if (method.Name.StartsWith("OrderBy") || method.Name.StartsWith("ThenBy"))
                {
                    // untyped orderby, must be late bound, use our comparison instead of the default
                    if (method.GetGenericArguments()[1] == typeof(object))
                    {
                        return(Expression.Call(typeof(Queryable), method.Name, method.GetGenericArguments(),
                                               this.Visit(m.Arguments[0]), this.Visit(m.Arguments[1]), Expression.Constant(this.OpenTypeMethodsImplementation)));
                    }
                }
            }

            return(base.VisitMethodCall(m));
        }
コード例 #3
0
        /// <summary>
        /// BinaryExpression visit method
        /// </summary>
        /// <param name="b">The BinaryExpression expression to visit</param>
        /// <returns>The visited BinaryExpression expression </returns>
        internal override Expression VisitBinary(BinaryExpression b)
        {
            MethodInfo method = b.Method;

            if (method != null && method.ReflectedType == typeof(OpenTypeMethods))
            {
                return(OpenTypeMethodsImplementation.ConvertMethodCall(method, this.Visit(b.Left), this.Visit(b.Right)));
            }

            return(base.VisitBinary(b));
        }
コード例 #4
0
        /// <summary>
        /// BinaryExpression visit method
        /// </summary>
        /// <param name="b">The BinaryExpression expression to visit</param>
        /// <returns>The visited BinaryExpression expression </returns>
        internal override Expression VisitUnary(UnaryExpression u)
        {
            MethodInfo method = u.Method;

            if (method != null && method.ReflectedType == typeof(OpenTypeMethods))
            {
                return(OpenTypeMethodsImplementation.ConvertMethodCall(method, this.Visit(u.Operand)));
            }

            return(base.VisitUnary(u));
        }
コード例 #5
0
 /// <summary>
 /// Creates a new instance of LateBoundExpressionVisitor
 /// </summary>
 /// <param name="evaluator">An evaluator class in which expressions will be bound to.</param>
 /// <param name="provider">The provider</param>
 internal LateBoundExpressionVisitor(OpenTypeMethodsImplementation openTypeImplementation, DSPMethodsImplementation dspImplementation)
 {
     this.OpenTypeMethodsImplementation = openTypeImplementation;
     this.DSPMethodsImplementation      = dspImplementation;
 }