Expression Trees in .Net 3.5 Framework (Basics)
Expression Trees - What's this ?
Will begin the post by trying to explain whats Expression Tree is all about and at the end of the post will try to explain why we need this.
In general, Expression Trees are basic tree structure which helps to represent any algebraic expression(Binary expressions – x < y). Usually with single root node with clusters of sub-nodes and ending with leaf nodes.
.Net 3.5 framework introduced this Expression Trees (Visual Studio 2008), helps translating executable code {or} Represent language-level( c# )code in the form of data, and visualize in a tree-like format.
Expression Trees – A Data Structure
Yes, in simple words Expression Trees are Data structure, which helps to store executable code blocks. An executable code could be any code block containing expressions of type delegate.
for ex.) Func<int, int, int> function = (a,b) => a + b;
here (a,b) => a + b is the executable code (an lambda expression) which is of a delegate type Func.
Creating an Expression Tree
Expression is an abstract class present in System.Linq.Expressions namespace.
a simple expression object initialization will look as below,
Expression<Func<int, int, int>> expression = (a,b) => a + b;
in the above code, we have created an expression instance of delegate type and refers to an executable code block( in this case a lambda expression “ (a,b) => a + b” )
Viewing an Expression Tree
Once we have created an expression instance as above, it can be visualized using a ExpressionTreeVisualizer( a free add-on available in MSDN –Linq samples). After the installation of this add on, in the debug mode while we perform a mouse hover on the expression instance variable we get an magnifier icon similar to the one shown below,
on clicking the image, we can view the complete executable code that we mapped in the form of a tree.
Body: Retrieve the body of the expression.
Parameters: Retrieve the parameters of the lambda expression.
NodeType: Gets the Expression Type for some node in the tree. Like (<), (>), those that add values together (+), Lambda etc.
Type: Gets the static type of the expression. In this case, the expression is of type Func<int, int, int>.
What’s the need for Expression Trees ?
Yes, i am able to sense the restless in each one of you, as to why we need such a data structure and what i am trying to demonstrate in this post. I hope the following advantages i am listing will do some justice to the need for Expression trees.
Advantages
1. Expression Tree –DOM:- it has its own DOM, with which we can traverse any of the tree node and retrieve data that we require.
BinaryExpression body = (BinaryExpression)expression.Body;
ParameterExpression left = (ParameterExpression)body.Left;
2. Expression Tree – Compilation:- converting data back into code, (i.e) once we have mapped the executable code block to an Expression instance, then we can just make use of the Compile method of the Expression class to execute the code block. below code we are compiling the same expression that we created above initially in the post.
int result = expression.Compile()(3, 5);
Console.WriteLine(result);
3. Expression Trees in LINQ:- Language Integrated Query, with the introduction of LINQ, the need for Expression Trees data structure became inevitable. To understand this, we should get back to the basics of LINQ to SQL.
Consider the following LINQ query,
var query = from c in db.Customers
where c.City == "Nantes" select new { c.City, c.CompanyName };
though the query is written in c# editor, the linq query is not directly complied into binaries by the c# compiler and sent to the SQL Server process to retrieve the data (because for the sql server to interpret the binaries and respond with result is non-sense).
So, the ideal think to do, is to convert the above linq into its equivalent string query and send across the wire to the SQL server process, so that it can interpret and respond with the desired result.
If so, then how to generate the best, efficient and equivalent string query ? this question lead to the invention of the Expression Tree Data structure, along with the effective built-in algo to convert the data structure into its equivalent string representations (in case of Linq to SQL).
If you drill into the type definition of the above linq query, you will notice that the query returns a IQueryable type and whose definition in turn looks as below,
public interface IQueryable : IEnumerable
{
Type ElementType { get; }
Expression Expression { get; }
IQueryProvider Provider { get; }
}
So now its apparent that whatever Linq to SQL query we write, it gets stored in the Expression data member of the IQueryable type, then the in-built algo of Linq to SQL is intelligent enough to generate the best equivalent sql query string by parsing through the data structure and send it across to the sql server process.
Hence with the above advantage what i have explained (one of the in-built implementation of Expression Trees), i am sure we developers have the freedom to improvise and make use of Expression Trees in best possible ways as demanded by our application.
Labels: .Net (C#), Expression Tree