private string TranslateMethodCall(MethodCallExpression node)
        {
            var methodName = node.Method.Name;
            MemberExpression leftExpression = null;
            var arguments = new List <LambdaExpression>();

            if (node.Method.DeclaringType == typeof(string))
            {
                string arg = Translate(node.Object);

                object[] stringArguments = node.Arguments.Select(UnQuote).OfType <ConstantExpression>().Select(exp => exp.Value).ToArray();

                switch (methodName)
                {
                case "StartsWith":
                    return($"({arg} like {CreateParameter(stringArguments[0] + "%", typeof(string))})");

                case "EndsWith":
                    return($"({arg} like {CreateParameter("%" + stringArguments[0], typeof(string))})");

                case "Contains":
                    return($"({arg} like {CreateParameter("%" + stringArguments[0] + "%", typeof(string))})");

                case "Trim":
                    return(string.Format(_sqlDialect.SqlFunction(SqlDialect.Function.Trim), stringArguments[0]));
                }

                throw new SqlExpressionTranslatorException(node.ToString());
            }

            if (node.Method.DeclaringType == typeof(QueryExtensions) && node.Arguments.Count > 1)
            {
                string arg = Translate(node.Arguments[0]);

                switch (methodName)
                {
                case nameof(QueryExtensions.IsAnyOf):
                case nameof(QueryExtensions.IsNotAnyOf):
                {
                    object argument = ExpressionEvaluator.Evaluate(node.Arguments.Skip(1).Select(UnQuote).First()).Value;

                    if (!(argument is IEnumerable enumerable))
                    {
                        throw new SqlExpressionTranslatorException(node.ToString());
                    }

                    var values = enumerable.Cast <object>().Select(o => CreateParameter(o));

                    if (methodName == nameof(QueryExtensions.IsNotAnyOf))
                    {
                        return($"({arg} not in ({string.Join(",", values)}))");
                    }
                    else
                    {
                        return($"({arg} in ({string.Join(",", values)}))");
                    }
                }

                case nameof(QueryExtensions.IsBetween):
                {
                    object[] args = node.Arguments.Skip(1).Select(UnQuote).OfType <ConstantExpression>().Select(exp => exp.Value).ToArray();

                    if (args.Length != 2)
                    {
                        throw new SqlExpressionTranslatorException(node.ToString());
                    }

                    var from = CreateParameter(args[0]);
                    var to   = CreateParameter(args[1]);

                    return($"({arg} between {from} and {to})");
                }
                }
            }

            if (node.Method.DeclaringType.IsConstructedGenericType && node.Method.DeclaringType.GetGenericTypeDefinition() == typeof(IDataSet <>))
            {
                leftExpression = node.Object as MemberExpression;
                arguments.AddRange(node.Arguments.Select(UnQuote).OfType <LambdaExpression>());
            }

            if (node.Method.DeclaringType == typeof(Enumerable) && node.Arguments.Count > 0)
            {
                leftExpression = node.Arguments[0] as MemberExpression;
                arguments.AddRange(node.Arguments.Skip(1).Select(UnQuote).OfType <LambdaExpression>());
            }

            if (leftExpression != null)
            {
                switch (methodName)
                {
                case "Any":
                case "Count":
                case "All":
                    return(TranslateOneToMany(
                               methodName,
                               leftExpression,
                               null,
                               arguments.Count > 0 ? arguments[0] : null
                               ));

                case "Sum":
                case "Avg":
                    return(TranslateOneToMany(
                               methodName,
                               leftExpression,
                               arguments[0],
                               null
                               ));
                }
            }

            throw new SqlExpressionTranslatorException(node.ToString());
        }
Esempio n. 2
0
        private string TranslateMethodCall(MethodCallExpression node)
        {
            var methodName = node.Method.Name;
            MemberExpression leftExpression = null;
            var arguments = new List <LambdaExpression>();

            if (node.Method.DeclaringType == typeof(string))
            {
                string arg = Translate(node.Object);

                object[] stringArguments = node.Arguments.Select(UnQuote).OfType <ConstantExpression>().Select(exp => exp.Value).ToArray();

                switch (methodName)
                {
                case "StartsWith":
                    return($"({arg} like {CreateParameter(stringArguments[0] + "%", typeof(string))})");

                case "EndsWith":
                    return($"({arg} like {CreateParameter("%" + stringArguments[0], typeof(string))})");

                case "Contains":
                    return($"({arg} like {CreateParameter("%" + stringArguments[0] + "%", typeof(string))})");

                case "Trim":
                    return(string.Format(_sqlDialect.SqlFunction(SqlDialect.Function.Trim), stringArguments[0]));
                }

                throw new SqlExpressionTranslatorException(node.ToString());
            }

            if (node.Method.DeclaringType.IsConstructedGenericType && node.Method.DeclaringType.GetGenericTypeDefinition() == typeof(IDataSet <>))
            {
                leftExpression = node.Object as MemberExpression;
                arguments.AddRange(node.Arguments.Select(UnQuote).OfType <LambdaExpression>());
            }

            if (node.Method.DeclaringType == typeof(Enumerable) && node.Arguments.Count > 0)
            {
                leftExpression = node.Arguments[0] as MemberExpression;
                arguments.AddRange(node.Arguments.Skip(1).Select(UnQuote).OfType <LambdaExpression>());
            }

            if (leftExpression != null)
            {
                switch (methodName)
                {
                case "Any":
                case "Count":
                case "All":
                    return(TranslateOneToMany(
                               methodName,
                               leftExpression,
                               null,
                               arguments.Count > 0 ? arguments[0] : null
                               ));

                case "Sum":
                case "Avg":
                    return(TranslateOneToMany(
                               methodName,
                               leftExpression,
                               arguments[0],
                               null
                               ));
                }
            }

            throw new SqlExpressionTranslatorException(node.ToString());
        }