Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda Expression Tree Parsing

I am trying to use Lambda Expressions in a project to map to a third party query API. So, I'm parsing the Expression tree by hand.

If I pass in a lambda expression like:

p => p.Title == "title"

everything works.

However, if my lambda expression looks like:

p => p.Title == myaspdropdown.SelectedValue

Using the .NET debugger, I don't see the actual value of that funciton. Instead I see something like:

p => p.Title = (value(ASP.usercontrols_myaspusercontrol_ascx).myaspdropdown.SelectedValue)

What gives? And when I try to grab the right side of the expression as a string, I get (value(ASP.usercontrols_myaspusercontrol_ascx).myaspdropdown.SelectedValue) instead of the actual value. How do I get the actual value?

like image 1000
Keith Fitzgerald Avatar asked Oct 26 '08 18:10

Keith Fitzgerald


People also ask

How do you use expression trees?

Expression Trees provide richer interaction with the arguments that are functions. You write function arguments, typically using Lambda Expressions, when you create LINQ queries. In a typical LINQ query, those function arguments are transformed into a delegate the compiler creates.

What is an expression tree explain with an example?

Each node in an expression tree is an expression. For example, an expression tree can be used to represent mathematical formula x < y where x, < and y will be represented as an expression and arranged in the tree like structure. Expression tree is an in-memory representation of a lambda expression.

What is expression tree in data structure?

An expression tree is a representation of expressions arranged in a tree-like data structure. In other words, it is a tree with leaves as operands of the expression and nodes contain the operators. Similar to other data structures, data interaction is also possible in an expression tree.


2 Answers

Remember that when you're dealing with the lambda expression as an expression tree, you don't have executable code. Rather you have a tree of expression elements, that make up the expression you wrote.

Charlie Calvert has a good post that discusses this in detail. Included is an example of using an expression visualiser for debugging expressions.

In your case, to get the value of the righthand side of the equality expression, you'll need to create a new lambda expression, compile it and then invoke it.

I've hacked together a quick example of this - hope it delivers what you need.

public class Class1
{
    public string Selection { get; set; }

    public void Sample()
    {
        Selection = "Example";
        Example<Book, bool>(p => p.Title == Selection);
    }

    public void Example<T,TResult>(Expression<Func<T,TResult>> exp)
    {
        BinaryExpression equality = (BinaryExpression)exp.Body;
        Debug.Assert(equality.NodeType == ExpressionType.Equal);

        // Note that you need to know the type of the rhs of the equality
        var accessorExpression = Expression.Lambda<Func<string>>(equality.Right);
        Func<string> accessor = accessorExpression.Compile();
        var value = accessor();
        Debug.Assert(value == Selection);
    }
}

public class Book
{
    public string Title { get; set; }
}
like image 125
Bevan Avatar answered Oct 08 '22 05:10

Bevan


To get the actual value, you need to apply the logic of the expression tree to whatever context you've got.

The whole point of expression trees is that they represent the logic as data rather than evaluating the expression. You'll need to work out what the lambda expression truly means. That may mean evaluating some parts of it against local data - you'll need to decide that for yourself. Expression trees are very powerful, but it's not a simple matter to parse and use them. (Ask anyone who's written a LINQ provider... Frans Bouma has bemoaned the difficulties several times.)

like image 39
Jon Skeet Avatar answered Oct 08 '22 06:10

Jon Skeet