Introduction

Expression Trees are Expressions arranged in a treelike data structure. Each node in the tree is a representation of an expression, an expression being code. An In-Memory representation of a Lambda expression would be an Expression tree, which holds the actual elements (i.e. code) of the query, but not its result. Expression trees make the structure of a lambda expression transparent and explicit.

Syntax

Parameters

Intro to Expression Trees

Where we came from

Expression trees are all about consuming “source code” at runtime. Consider a method which calculates the sales tax due on a sales order decimal CalculateTotalTaxDue(SalesOrder order). Using that method in a .NET program is easy — you just call it decimal taxDue = CalculateTotalTaxDue(order);. What if you want to apply it to all the results from a remote query (SQL, XML, a remote server, etc)? Those remote query sources cannot call the method! Traditionally, you would have to invert the flow in all these cases. Make the entire query, store it in memory, then loop through the results and calculate tax for each result.

How to avoid flow inversion’s memory and latency problems

Expression trees are data structures in a format of a tree, where each node holds an expression. They are used to translate the compiled instructions (like methods used to filter data) in expressions which could be used outside of the program environment such as inside a database query.

The problem here is that a remote query cannot access our method. We could avoid this problem if instead, we sent the instructions for the method to the remote query. In our CalculateTotalTaxDue example, that means we send this information:

  1. Create a variable to store the total tax
  2. Loop through all the lines on the order
  3. For each line, check if the product is taxable
  4. If it is, multiply the line total by the applicable tax rate and add that amount to the total
  5. Otherwise do nothing

With those instructions, the remote query can perform the work as it’s creating the data.

There are two challenges to implementing this. How do you transform a compiled .NET method into a list of instructions, and how do you format the instructions in a way that they can be consumed by the remote system?