Beispiel #1
0
        public Expression <Func <TModel, TResult> > Translate <TModel, TResult>(ODataLambdaExpression expression)
        {
            KnownAssembly = typeof(TModel).Assembly;
            var lambda = (LambdaExpression)VisitLambda(expression, typeof(TModel));

            return(Expression.Lambda <Func <TModel, TResult> >(lambda.Body, lambda.Parameters));
        }
Beispiel #2
0
        private Expression VisitLambda(ODataLambdaExpression node, Type parameterType = null)
        {
            var param = node.Parameters.Select(p => VisitParameter(p, parameterType)).Cast <ParameterExpression>().ToArray();

            var body = Visit(node.Body);

            return(Expression.Lambda(body, param));
        }
        public void LambdaExpression()
        {
            var tparameter = ODataExpression.Parameter("t");
            var cparameter = ODataExpression.Parameter("c");
            var l1         = new ODataLambdaExpression
            {
                Body       = ODataExpression.PropertyOrField("Items", cparameter),
                Parameters = new[] { cparameter }
            };

            var aparameter = ODataExpression.Parameter("a");
            var bparameter = ODataExpression.Parameter("b");
            var l2         = new ODataLambdaExpression
            {
                Body       = ODataExpression.Add(ODataExpression.PropertyOrField("Id", aparameter), ODataExpression.PropertyOrField("Id", bparameter)),
                Parameters = new[] { aparameter, bparameter }
            };

            var method = new ODataMethodCallExpression
            {
                Context    = ODataExpression.PropertyOrField("Customers", tparameter),
                MethodName = "SelectMany",
                Arguments  = new ODataExpression[]
                {
                    l1, l2
                }
            };

            var expression = new ODataLambdaExpression
            {
                Body       = method,
                Parameters = new [] { tparameter }
            };
            //t => t.Customers.SelectMany(c => c.Customers, (a, b) => (a.Id + b.Id))
            //t => t.Customers.SelectMany(c => c.Customers, (a, b) => (a.Id + b.Id))


            var methods =
                typeof(Queryable).GetMethods()
                .Where(x => x.Name == "SelectMany" && x.GetParameters().Length == 3)
                .ToArray();

            foreach (var methodInfo in methods)
            {
                //   var arguments = methodInfo.GetGenericArguments();

                // var parameter = DynamicExpression.Parameter(arguments[0], "t");

                //   var dd = DynamicExpression.Property(parameter, "Customers");
                //
            }


            //var expr = Linq.Linq.Expr<Customer, IEnumerable<int>>(t => t.Customers.SelectMany(c => c.Items, (a, b) => a.Id + b.Id));
            //var translator = new QueryTranslator();

            //var d = translator.Invoke<Customer, IEnumerable<int>>(expression);
        }
        private ODataExpression ParseIdentifier(bool minus, ODataParameterExpression parameter, ODataExpression parent = null, IDictionary <string, ODataParameterExpression> lambdaParameters = null)
        {
            for (_current++; _current < _source.Length; _current++)
            {
                var c = _source[_current];

                if (!IsIdentifierChar(c))
                {
                    break;
                }
            }

            var name = _source.Substring(_offset, _current - _offset);

            var lastOffset = _offset;

            _offset = _current;

            switch (name)
            {
            case "INF":
                return(ODataExpression.Constant(double.PositiveInfinity));

            case "-INF":
                return(ODataExpression.Constant(double.NegativeInfinity));

            case "Nan":
                return(ODataExpression.Constant(double.NaN));

            case "true":
                return(ODataExpression.Constant(true));

            case "false":
                return(ODataExpression.Constant(false));

            case "null":
                return(ODataExpression.Constant(null, typeof(object)));

            case "-":
            {
                return(new ODataUnaryExpression(ExpressionType.Negate));
            }

            default:
                if (minus)
                {
                    // Reset the offset.
                    _offset = lastOffset + 1;

                    return(new ODataUnaryExpression(ExpressionType.Negate));
                }
                break;
            }

            if (_offset < _source.Length)
            {
                switch (_source[_offset])
                {
                case '\'':
                {
                    StringType stringType;

                    switch (name)
                    {
                    case "X": stringType = StringType.Binary; break;

                    case "binary": stringType = StringType.Binary; break;

                    case "datetime": stringType = StringType.DateTime; break;

                    case "guid": stringType = StringType.Guid; break;

                    case "time": stringType = StringType.Time; break;

                    case "datetimeoffset": stringType = StringType.DateTimeOffset; break;

                    default: stringType = StringType.None; break;
                    }

                    if (stringType != StringType.None && _source[_offset] == '\'')
                    {
                        var content = ParseString();

                        return(ParseSpecialString((string)content.Value, stringType));
                    }

                    if (stringType == StringType.None)
                    {
                        var content = ParseString();

                        return(ParceValue(name, (string)content.Value));
                    }

                    break;
                }

                case ':':
                {
                    _offset++;

                    var depth = 0;

                    var p = ODataExpression.Parameter(name);

                    var lp = new Dictionary <string, ODataParameterExpression>(lambdaParameters ?? new Dictionary <string, ODataParameterExpression>());

                    lp[p.Name] = p;

                    var tokens = new List <ODataExpression>();

                    while (true)
                    {
                        var token = GetNext(parameter, null, lp);

                        if (token == null)
                        {
                            break;
                        }

                        if (token.NodeType == ExpressionType.Default)
                        {
                            var syntaxExpressionToken = (ODataSyntaxExpression)token;

                            if (syntaxExpressionToken.Syntax == ',')
                            {
                                _offset--;
                                break;
                            }

                            if (syntaxExpressionToken.Syntax == '(')
                            {
                                depth++;
                            }

                            if (syntaxExpressionToken.Syntax == ')')
                            {
                                if (depth == 0)
                                {
                                    _offset--;
                                    break;
                                }

                                depth--;
                            }
                        }

                        tokens.Add(token);
                    }

                    var body = CreateExpression(ConvertToRpn(tokens));

                    var lambdaExpression = new ODataLambdaExpression
                    {
                        Parameters = new[] { p },
                        Body       = body
                    };

                    return(lambdaExpression);
                }

                case '/':
                {
                    _offset++;

                    if (lambdaParameters != null && lambdaParameters.ContainsKey(name) && parent == null)
                    {
                        return(ParseIdentifier(false, parameter, lambdaParameters[name], lambdaParameters));
                    }
                    if (name.StartsWith("Ase.") && parent != null && name.Substring(4) == parent.ToString().Replace(parameter.ToString() + ".", ""))
                    {
                        return(ParseIdentifier(false, parameter, parent, lambdaParameters));
                    }

                    return(ParseIdentifier(false, parameter, ODataExpression.PropertyOrField(name, parent ?? parameter), lambdaParameters));
                }

                case '(':    //Если следующий элемент скобка, значит это функция
                {
                    var depth     = 0;
                    var comma     = false;
                    var arguments = new List <ODataExpression>();
                    var temp      = new List <ODataExpression>();

                    while (true)
                    {
                        var token = GetNext(parameter, null, lambdaParameters);

                        if (token == null)
                        {
                            break;
                        }
                        var syntax = token as ODataSyntaxExpression;

                        if (syntax != null && syntax.Syntax == ',')
                        {
                            if (temp.Any())
                            {
                                var tokens = ConvertToRpn(temp.ToArray());

                                var expression = CreateExpression(tokens);

                                arguments.Add(expression);

                                temp = new List <ODataExpression>();

                                comma = true;
                            }
                            else
                            {
                                throw new Exception("extra comma");
                            }
                        }
                        else
                        {
                            if (syntax != null && syntax.Syntax == '(')
                            {
                                if (comma)
                                {
                                    throw new Exception("extra comma");
                                }

                                depth++;
                            }

                            if (syntax != null && syntax.Syntax == ')')
                            {
                                if (comma)
                                {
                                    throw new Exception("extra comma");
                                }

                                depth--;
                            }

                            if (syntax == null ||
                                !(syntax.Syntax == '(' && depth == 1) && !(syntax.Syntax == ')' && depth == 0))
                            {
                                temp.Add(token);
                            }

                            comma = false;

                            if (depth == 0)
                            {
                                if (temp.Any())
                                {
                                    var tokens = ConvertToRpn(temp.ToArray());

                                    var expression = CreateExpression(tokens);


                                    arguments.Add(expression);
                                }

                                break;
                            }
                        }
                    }

                    if (depth != 0)
                    {
                        throw new Exception("Parenthesis mismatch");
                    }


                    var methodCallExpression = new ODataMethodCallExpression
                    {
                        Context    = parent,
                        MethodName = name,
                        Arguments  = arguments.ToArray()
                    };

                    if (_offset < _source.Length && _source[_offset] == '/')
                    {
                        _current++;

                        _offset = _offset + 1;


                        return(ParseIdentifier(false, parameter, methodCallExpression, lambdaParameters));
                    }


                    return(methodCallExpression);
                }
                }
            }

            if (name.IsOperator())
            {
                var expressionType = name.GetExpressionType();

                if (name.IsUnaryOperator())
                {
                    return(ODataExpression.MakeUnary(expressionType, null));
                }

                if (name.IsArithmeticOperator() || name.IsLogicalOperator())
                {
                    return(ODataExpression.MakeBinary(expressionType, null, null));
                }
            }

            if (parent == null && lambdaParameters != null && lambdaParameters.ContainsKey(name))
            {
                return(lambdaParameters[name]);
            }

            if (name.Contains("."))
            {
                var type = GetType(name);
                return(ODataExpression.Constant(type));
            }

            return(ODataExpression.PropertyOrField(name, parent ?? parameter));
        }
Beispiel #5
0
 public Expression <Func <TResult> > Translate <TResult>(ODataLambdaExpression expression)
 {
     expression.Parameters = new ODataParameterExpression[0];
     return((Expression <Func <TResult> >)VisitLambda(expression));
 }
Beispiel #6
0
 public LambdaExpression Translate(ODataLambdaExpression expression, Type modelType)
 {
     KnownAssembly = modelType.Assembly;
     return((LambdaExpression)VisitLambda(expression, modelType));
 }
 public LambdaExpression Translate(ODataLambdaExpression expression, Type modelType)
 {
     return((LambdaExpression)VisitLambda(expression, modelType));
 }