Building LINQ Expressions (Part 1)

Home / Building LINQ Expressions (Part 1)

I’ve said it before, and it bears repeating. LINQ is one of those features in .NET that keeps me using it. In-line queries that allow you to expressively search lists, with the declarative query syntax, is very appealing. Sure, under the covers, it’s performing the heavy lifting, iteration, and such, but the SQL-like lambda expressions are incredibly powerful.

However, sometimes we need something even more dynamic.

Imagine that I provide an end-user with a UI and allow them to search by one or many data columns via an arbitrary search term and operator. It’s not possible to encapsulate that within a compile-time LINQ .Where() expression. Our general Lambda operator and operation statically tie our query to specific model properties. For dynamically searching data, we could overcome this with a boat-load of switch/case statements, but that, in my mind, deviates from elegant, readable, and simple code. As LINQ does our heavy lifting, it’s possible to use LINQ’s Expression Builder to help with that heavy lifting in a repeatable fashion.

What does a typical LINQ expression look like? Here’s a very simple example. Let’s say that we have a Model () and we want to search through List on an arbitrary Model property, which we will assume is a string, where the string Contains our search term. To complicate matters, we only know the Model property by name rather than having a “static handle” on it.

private static Expression<Func<T, bool>> GetStringExpression<T>(string propertyName, string searchTerm)
    ParameterExpression parameter = Expression.Parameter(typeof(T), "item");
    Expression property = Expression.Property(parameter, propertyName);
    MethodInfo miOperator = typeof(string).GetMethod("Contains", new Type[] { typeof(string) });
    Expression target = Expression.Constant(searchTerm, typeof(string));

    // Build expression tree that represents data.Where(x => x.Property.Contains(searchTerm))
    Expression method = Expression.Call(property, miOperator, target);
    return Expression.Lambda<Func<T, bool>>(method, parameter);

This code is effectively building LINQ Expressions for every operation and value involved in our predicate (Lambda) that we’re going to return. Interestingly, we also use a bit of reflection to get the string “Contains” method. LINQ knows how to convert this method (and many other built-in .NET methods) to binary expressions. Note that even our search term is converted to a constant Expression. Once we build up what we want our expression to be, we call Expression.Lambda to convert it to an expression tree that represents our known delegate (Func).

Using this in practice, imagine when we typically use the .Where() method and pass in a static lambda expression:

var list = myList.Where(x => x.Name.Contains("Steve")).ToList();

With our shiny new Expression builder, the above code becomes more dynamic:

var exp = GetStringExpression<Person>("Name", "Steve");
var list = myList.Where(exp).ToList();

We could use the above code to dynamically search any string property of “Person.” All that would have to change is the property name that we’re passing into our Expression builder.

This an initial, cursory, view of building LINQ expressions. LINQ Expressions are extremely powerful and allow you to do things that would otherwise be tedious, or completely annihilate the DRY concept. I’ll be diving into this topic in greater detail in a future post.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.