Fundamentals - Part 6

08/31/2025
2 minute read

Expression Trees

If you’ve worked with Entity Framework (EF), you’ve benefited from expression trees — even if you didn’t realize it. Expression trees allow C# code to be represented as data, which EF can then translate into SQL queries. This concept may seem abstract at first, but understanding it helps demystify how EF (and other LINQ providers) actually work.


What Is an Expression Tree?

Normally, when you write a lambda, it compiles to executable IL code:

Func<int, bool> isEven = x => x % 2 == 0;

But with expression trees, your lambda can be captured as data (an abstract syntax tree), rather than compiled code:

Expression<Func<int, bool>> isEvenExpr = x => x % 2 == 0;

Instead of executable code, isEvenExpr now holds a structured representation of the lambda that you can inspect at runtime.

Inspecting an Expression Tree

Expression<Func<int, bool>> expr = x => x % 2 == 0;

Console.WriteLine(expr.Body); // (x % 2 == 0) Console.WriteLine(expr.Parameters[0].Name); // x

You can see the shape of the expression: the parameter x, the modulus operator, and the equality check. This is the same information EF reads to turn your LINQ queries into SQL.

Entity Framework and Expression Trees

//When you write
var query = db.Users.Where(u => u.Name.StartsWith("A"));

//EF doesn’t just execute that lambda. Instead, it inspects the expression tree: Expression<Func<User, bool>> predicate = u => u.Name.StartsWith("A");

--It then walks the tree, sees you’re calling StartsWith("A") on u.Name, and generates equivalent SQL:
SELECT * FROM Users WHERE Name LIKE 'A%'

Without expression trees, EF wouldn’t know how to translate your LINQ query to SQL.


Creating an expression tree manually:

// Build: x => x > 5
ParameterExpression param = Expression.Parameter(typeof(int), "x");
ConstantExpression constant = Expression.Constant(5);
BinaryExpression body = Expression.GreaterThan(param, constant);

var lambda = Expression.Lambda<Func<int, bool>>(body, param);

Console.WriteLine(lambda); // x => (x > 5)

This might look verbose, but it shows how expressions are constructed piece by piece.

When Do You Need to Know This?

  • If you use EF (or any LINQ provider): understanding expression trees explains why some methods translate to SQL and others don’t.
  • If you build APIs or frameworks: expression trees let you analyze user code at runtime.
  • If you enjoy C# internals: it’s one of the most powerful features the language offers.

Final Thoughts

Expression trees let your C# code be treated as data. This is the trick that enables LINQ providers like EF to turn lambdas into SQL.

While you may never write expression trees manually in day-to-day code, understanding them gives you a clearer picture of how EF and similar tools work behind the scenes.

An error has occurred. This application may no longer respond until reloaded. Reload x