Search code examples
c#linqexpressionvisitor

Resolve ParameterExpression to actual Expression


I have written a LINQ-Provider which works perfectly but with one exception. It translates LINQ-Queries to ODATA-URL standards.

If I have the following LINQ-Statement:

.Select(x => x.Name.ToLower()).OrderByDescending(x => x)

And when I am visiting the expression tree with an expression visitor, I'll get an expression part (OrderByDescending) which type is ParameterExpression.

IntelliSense for ParameterExpression

My Question is now: How can I get to the selected x.Name.ToLower() expression? So that I can translate the orderBy statement to

$orderby=tolower(Name) desc

// Edit: With other words: I have a ParameterExpression {x => x}. I want this expression to be resolved to {x => x.Name.ToLower()}


Solution

  • Two problems with your code:

    1) The LINQ expression above does not mean /Entities?$orderby=tolower(Name) desc. There's actually no way to translate it to OData. The LINQ query would take all the entities, get their Name property and return a list of strings (the names) which are lower cased. It would also sort the list (descending).

    2) The expression tree for such an expression looks like:

    Call OrderBy
    - Argument 1 = Call Select
        - Argument 1 = Entities
        - Argument 2 = Lambda with parameter x(1)
           Body = ToLower(x(1).Name)
    - Argument 2 = Lambda with parameter x(2)
       Body = x(2)
    

    x(1) and x(2) are ParameterExpression nodes, which represent a parameter to the lambdas in the Select and OrderBy calls. Replacing the x(2) with the Body of the lambda of the Select (ToLower(x(1).Name)) would not work. First of all that body has x(1) parameter in it, which has no meaning in the context of the second lambda. And second, it would change the meaning of the expression.

    To get $orderby=tolower(Name) desc, the LINQ expression on the input would have to look something like:

    Entities.OrderByDescending(x => x.Name.ToLower())