/// <summary>
        ///     Visits a method call expression.
        /// </summary>
        /// <param name="methodCallExpression"> The expression to visit. </param>
        /// <returns>
        ///     An Expression.
        /// </returns>
        protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
        {
            Check.NotNull(methodCallExpression, nameof(methodCallExpression));

            var operand = Visit(methodCallExpression.Object);

            if (operand != null ||
                methodCallExpression.Object == null)
            {
                var arguments
                    = methodCallExpression.Arguments
                      .Where(e => !(e.RemoveConvert() is QuerySourceReferenceExpression) &&
                             !IsNonTranslatableSubquery(e.RemoveConvert()))
                      .Select(e => (e.RemoveConvert() as ConstantExpression)?.Value is Array || e.RemoveConvert().Type == typeof(DbFunctions)
                            ? e
                            : Visit(e))
                      .Where(e => e != null)
                      .ToArray();

                if (arguments.Length == methodCallExpression.Arguments.Count)
                {
                    var boundExpression
                        = operand != null
                            ? Expression.Call(operand, methodCallExpression.Method, arguments)
                            : Expression.Call(methodCallExpression.Method, arguments);

                    var translatedExpression = _methodCallTranslator.Translate(boundExpression);

                    if (translatedExpression != null)
                    {
                        return(translatedExpression);
                    }
                }
            }

            if (AnonymousObject.IsGetValueExpression(methodCallExpression, out QuerySourceReferenceExpression querySourceReferenceExpression))
            {
                var selectExpression
                    = _queryModelVisitor.TryGetQuery(querySourceReferenceExpression.ReferencedQuerySource);

                if (selectExpression != null)
                {
                    var projectionIndex
                        = (int)((ConstantExpression)methodCallExpression.Arguments.Single()).Value;

                    return(selectExpression.BindSubqueryProjectionIndex(
                               projectionIndex,
                               querySourceReferenceExpression.ReferencedQuerySource));
                }
            }

            return(TryBindMemberOrMethodToSelectExpression(methodCallExpression, (expression, visitor, binder)
                                                           => visitor.BindMethodCallExpression(expression, binder))
                   ?? _queryModelVisitor.BindLocalMethodCallExpression(methodCallExpression)
                   ?? _queryModelVisitor.BindMethodToOuterQueryParameter(methodCallExpression));
        }
        /// <summary>
        /// 访问NOT相关表达式。
        /// </summary>
        /// <param name="unaryExpression">一元运算符表达式。</param>
        /// <returns>返回表达式。</returns>
        protected virtual Expression VisitNot(UnaryExpression unaryExpression)
        {
            var memberExpression = unaryExpression.Operand as MemberExpression;

            if (memberExpression != null)
            {
                var expr = memberExpression.Expression;
                if (expr.NodeType == ExpressionType.Convert)
                {
                    expr = expr.RemoveConvert();
                }
                switch (expr.NodeType)
                {
                case ExpressionType.Parameter:
                    Visit(Expression.Equal(memberExpression, Expression.Constant(false)));
                    break;

                case ExpressionType.MemberAccess:
                case ExpressionType.Constant:
                    AppendInvoke(unaryExpression);
                    break;
                }
                return(unaryExpression);
            }

            var expression           = unaryExpression.Operand;
            var methodCallExpression = expression as MethodCallExpression;

            if (methodCallExpression != null)
            {
                expression = _methodCallTranslator.Translate(methodCallExpression);
            }

            var isNullExpression = expression as IsNullExpression;

            if (isNullExpression != null)
            {
                return(VisitIsNotNull(isNullExpression));
            }

            return(unaryExpression);
        }
예제 #3
0
        /// <summary>
        ///     Tries to translate the Method-call to some N1QL expression. Currently only implemented for "Contains() - LIKE"
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        protected override Expression VisitMethodCall(MethodCallExpression expression)
        {
            IMethodCallTranslator methodCallTranslator = QueryGenerationContext.MethodCallTranslatorProvider.GetTranslator(expression);

            if (methodCallTranslator != null)
            {
                return(methodCallTranslator.Translate(expression, this));
            }

            return(base.VisitMethodCall(expression));
        }
        /// <summary>
        ///     Visits a method call expression.
        /// </summary>
        /// <param name="methodCallExpression"> The expression to visit. </param>
        /// <returns>
        ///     An Expression.
        /// </returns>
        protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
        {
            Check.NotNull(methodCallExpression, nameof(methodCallExpression));

            var operand = Visit(methodCallExpression.Object);

            if (operand != null ||
                methodCallExpression.Object == null)
            {
                var arguments
                    = methodCallExpression.Arguments
                      .Where(e => !(e is QuerySourceReferenceExpression) &&
                             !(e is SubQueryExpression))
                      .Select(e => (e as ConstantExpression)?.Value is Array ? e : Visit(e))
                      .Where(e => e != null)
                      .ToArray();

                if (arguments.Length == methodCallExpression.Arguments.Count)
                {
                    var boundExpression
                        = operand != null
                            ? Expression.Call(operand, methodCallExpression.Method, arguments)
                            : Expression.Call(methodCallExpression.Method, arguments);

                    var translatedExpression = _methodCallTranslator.Translate(boundExpression);

                    if (translatedExpression != null)
                    {
                        return(translatedExpression);
                    }
                }
            }

            var expression
                = _queryModelVisitor
                  .BindMethodCallExpression(methodCallExpression, CreateAliasedColumnExpression)
                  ?? _queryModelVisitor.BindLocalMethodCallExpression(methodCallExpression);

            if (expression == null &&
                _bindParentQueries)
            {
                expression
                    = TryBindParentExpression(
                          _queryModelVisitor.ParentQueryModelVisitor,
                          qmv => qmv.BindMethodCallExpression(methodCallExpression, CreateAliasedColumnExpressionCore));
            }

            return(expression
                   ?? _queryModelVisitor.BindMethodToOuterQueryParameter(methodCallExpression));
        }
        protected override Expression VisitMethodCall(MethodCallExpression expression)
        {
            Check.NotNull(expression, nameof(expression));

            var operand = Visit(expression.Object);

            if (operand != null ||
                expression.Object == null)
            {
                var arguments
                    = expression.Arguments
                      .Where(e => !(e is QuerySourceReferenceExpression) &&
                             !(e is SubQueryExpression))
                      .Select(Visit)
                      .Where(e => e != null)
                      .ToArray();

                if (arguments.Length == expression.Arguments.Count)
                {
                    var boundExpression
                        = operand != null
                            ? Expression.Call(operand, expression.Method, arguments)
                            : Expression.Call(expression.Method, arguments);

                    var translatedExpression =
                        _methodCallTranslator.Translate(boundExpression);

                    if (translatedExpression != null)
                    {
                        return(translatedExpression);
                    }
                }
            }

            var aliasExpression
                = _queryModelVisitor
                  .BindMethodCallExpression(expression, CreateAliasedColumnExpression);

            if (aliasExpression == null &&
                _bindParentQueries)
            {
                aliasExpression
                    = _queryModelVisitor?.ParentQueryModelVisitor
                      .BindMethodCallExpression(expression, CreateAliasedColumnExpressionCore);
            }

            return(aliasExpression);
        }