src/Inflatable/LinqExpression/QueryTranslator.cs
/// <summary>
/// Visits the children of the <see cref="T:System.Linq.Expressions.MethodCallExpression"/>.
/// </summary>
/// <param name="node">The expression to visit.</param>
/// <returns>
/// The modified expression, if it or any subexpression was modified; otherwise, returns the
/// original expression.
/// </returns>
/// <exception cref="NotSupportedException"></exception>
Visits the children of the .
Visits the children of the .
protected override Expression? VisitMethodCall(MethodCallExpression node)
        {
            if (node is null)
                return node;
            if (node.Method.DeclaringType == typeof(Queryable))
            {
                if (node.Method.Name == "Where")
                {
                    node = (MethodCallExpression)Evaluator.PartialEval(node);
                    Visit(node.Arguments[0]);
                    var lambda = (LambdaExpression)StripQuotes(node.Arguments[1]);
                    var CurrentClause = new WhereVisitor<TObject>(Count).WhereProjection(lambda.Body);
                    ++Count;
                    foreach (var Source in Builders.Keys)
                    {
                        Builders[Source].WhereClause.Combine(CurrentClause.Copy());
                    }
                    return node;
                }
                if (node.Method.Name == "Select")
                {
                    Visit(node.Arguments[0]);
                    var lambda = (LambdaExpression)StripQuotes(node.Arguments[1]);
                    var Columns = new ColumnProjector().ProjectColumns(lambda.Body);
                    foreach (var Source in Builders.Keys)
                    {
                        var ParentMappings = Source.GetChildMappings(typeof(TObject))
                                                   .SelectMany(x => Source.GetParentMapping(x.ObjectType))
                                                   .Distinct();
                        foreach (var Column in Columns)
                        {
                            if (ParentMappings.Any(x => x.ContainsProperty(Column.Name)))
                            {
                                Builders[Source].SelectValues.Add(Column);
                            }
                        }
                    }
                    return node;
                }
                if (node.Method.Name == "ThenBy"
                    || node.Method.Name == "OrderBy"
                    || node.Method.Name == "OrderByDescending"
                    || node.Method.Name == "ThenByDescending")
                {
                    Visit(node.Arguments[0]);
                    var lambda = (LambdaExpression)StripQuotes(node.Arguments[1]);
                    var Columns = new ColumnProjector().ProjectColumns(lambda.Body);
                    foreach (var Source in Builders.Keys)
                    {
                        var ParentMappings = Source.GetChildMappings(typeof(TObject))
                                                   .SelectMany(x => Source.GetParentMapping(x.ObjectType))
                                                   .Distinct();
                        foreach (var Column in Columns)
                        {
                            if (ParentMappings.Any(x => x.ContainsProperty(Column.Name)))
                            {
                                Builders[Source].OrderByValues.Add(new OrderByClause(Builders[Source].OrderByValues.Count,
                                    Column,
                                    node.Method.Name.Contains("Descending", StringComparison.OrdinalIgnoreCase) ? Direction.Descending : Direction.Ascending));
                            }
                        }
                    }
                    return node;
                }
                if (node.Method.Name == "Distinct")
                {
                    Visit(node.Arguments[0]);
                    foreach (var Source in Builders.Keys)
                    {
                        Builders[Source].Distinct = true;
                    }
                    return node;
                }
                if (node.Method.Name == "First"
                    || node.Method.Name == "FirstOrDefault"
                    || node.Method.Name == "Single"
                    || node.Method.Name == "SingleOrDefault")
                {
                    Visit(node.Arguments[0]);
                    foreach (var Source in Builders.Keys)
                    {
                        Builders[Source].Top = 1;
                    }
                    return node;
                }
                if (node.Method.Name == "Take")
                {
                    Visit(node.Arguments[0]);
                    foreach (var Source in Builders.Keys)
                    {
                        Builders[Source].Top = (int)((node.Arguments[1] as ConstantExpression)?.Value ?? 1);
                    }
                    return node;
                }
                if (node.Method.Name == "Skip")
                {
                    Visit(node.Arguments[0]);
                    foreach (var Source in Builders.Keys)
                    {
                        Builders[Source].Skip = (int)((node.Arguments[1] as ConstantExpression)?.Value ?? 1);
                    }
                    return node;
                }
                if (node.Method.Name == "Count")
                {
                    Visit(node.Arguments[0]);
                    foreach (var Source in Builders.Keys)
                    {
                        Builders[Source].Count = true;
                    }
                    return node;
                }
            }
            throw new NotSupportedException($"The method '{node.Method.Name}' is not supported.");
        }
protected override Expression ? VisitMethodCall ( MethodCallExpression node ) { if ( node is null ) return node ; if ( node . Method . DeclaringType == typeof ( Queryable ) ) { if ( node . Method . Name == " " ) { node = ( MethodCallExpression ) Evaluator . PartialEval ( node ) ; Visit ( node . Arguments [ 0 ] ) ; var lambda = ( LambdaExpression ) StripQuotes ( node . Arguments [ 1 ] ) ; var CurrentClause = new WhereVisitor < TObject > ( Count ) . WhereProjection ( lambda . Body ) ; ++ Count ; foreach ( var Source in Builders . Keys ) { Builders [ Source ] . WhereClause . Combine ( CurrentClause . Copy ( ) ) ; } return node ; } if ( node . Method . Name == " " ) { Visit ( node . Arguments [ 0 ] ) ; var lambda = ( LambdaExpression ) StripQuotes ( node . Arguments [ 1 ] ) ; var Columns = new ColumnProjector ( ) . ProjectColumns ( lambda . Body ) ; foreach ( var Source in Builders . Keys ) { var ParentMappings = Source . GetChildMappings ( typeof ( TObject ) ) . SelectMany ( x => Source . GetParentMapping ( x . ObjectType ) ) . Distinct ( ) ; foreach ( var Column in Columns ) { if ( ParentMappings . Any ( x => x . ContainsProperty ( Column . Name ) ) ) { Builders [ Source ] . SelectValues . Add ( Column ) ; } } } return node ; } if ( node . Method . Name == " " || node . Method . Name == " " || node . Method . Name == " " || node . Method . Name == " " ) { Visit ( node . Arguments [ 0 ] ) ; var lambda = ( LambdaExpression ) StripQuotes ( node . Arguments [ 1 ] ) ; var Columns = new ColumnProjector ( ) . ProjectColumns ( lambda . Body ) ; foreach ( var Source in Builders . Keys ) { var ParentMappings = Source . GetChildMappings ( typeof ( TObject ) ) . SelectMany ( x => Source . GetParentMapping ( x . ObjectType ) ) . Distinct ( ) ; foreach ( var Column in Columns ) { if ( ParentMappings . Any ( x => x . ContainsProperty ( Column . Name ) ) ) { Builders [ Source ] . OrderByValues . Add ( new OrderByClause ( Builders [ Source ] . OrderByValues . Count , Column , node . Method . Name . Contains ( " " , StringComparison . OrdinalIgnoreCase ) ? Direction . Descending : Direction . Ascending ) ) ; } } } return node ; } if ( node . Method . Name == " " ) { Visit ( node . Arguments [ 0 ] ) ; foreach ( var Source in Builders . Keys ) { Builders [ Source ] . Distinct = true ; } return node ; } if ( node . Method . Name == " " || node . Method . Name == " " || node . Method . Name == " " || node . Method . Name == " " ) { Visit ( node . Arguments [ 0 ] ) ; foreach ( var Source in Builders . Keys ) { Builders [ Source ] . Top = 1 ; } return node ; } if ( node . Method . Name == " " ) { Visit ( node . Arguments [ 0 ] ) ; foreach ( var Source in Builders . Keys ) { Builders [ Source ] . Top = ( int ) ( ( node . Arguments [ 1 ] as ConstantExpression ) ? . Value ?? 1 ) ; } return node ; } if ( node . Method . Name == " " ) { Visit ( node . Arguments [ 0 ] ) ; foreach ( var Source in Builders . Keys ) { Builders [ Source ] . Skip = ( int ) ( ( node . Arguments [ 1 ] as ConstantExpression ) ? . Value ?? 1 ) ; } return node ; } if ( node . Method . Name == " " ) { Visit ( node . Arguments [ 0 ] ) ; foreach ( var Source in Builders . Keys ) { Builders [ Source ] . Count = true ; } return node ; } } throw new NotSupportedException ( $" The method ' { node . Method . Name } ' is not supported. " ) ; }
Visits the children of the .
Visits the children of the .
The modified expression, if it or any subexpression was modified; otherwise, returns the
original expression.
The modified expression if it or any subexpression was modified ; otherwise returns the original expression .
None
node
MethodCallExpression
The expression to visit.
The expression to visit .