Dynamic Sorting and Filtering in C#

If you ever wondered how you could dynamically filter and/or sort your queries without having to write a huge switch statement with all the possible properties and operations, you've come to the right place!

Today we'll see how we can generate these types of operations at runtime and on the fly. I have packaged everything in this NuGet package, it's code is available in this GitHub repository.

For the sake of this blog post, let's assume that we're building an E-Commerce website.

Sorting

Imagine that in your Administration dashboard, you're displaying a list of products in a table. You were asked to add the ability to sort that table based on multiple fields.

Manual Approach

The simplest and most straightforward approach would be the following:

Which can be used like this:

As you can see, it's “a lot” of code for something so straightforward.
If you want to order by other properties, you'll have to add them to the switch statement and repeat the same thing over and over.
Again, if you want to perform a descending order by, you'll have to add even more code.

Dynamic Approach

Using DynamicExpressions.NET, all you have to do is this:

And voila! In 2 lines, we get a dynamic property getter (which replaces that “huge” switch statement) and the ability to use it wherever we want.

The library generates an Expression Tree almost the same as the one that gets generated in the manual approach, so the performance is practically the same!

Filtering

Imagine now that you're working on the client-side of the E-Commerce website. You've been tasked to add the ability for users/customers to filter the products list.

Manual Approach

The above approach assumes that it's the backend who decides what filters to apply, but what if it's the frontend who does? You will then have to add a FilterOperator and add a lot more code to handle all the cases for all the fields.

Dynamic Approach

Using DynamicExpressions.NET, all you have to do is this:

Again, we are set in 2 lines of code. The library generates a “performant” Expression Tree that handles almost all cases. The operatorSentByUser is an enumerator that handles all the basic operations (e.g. Equals, Contains, …).

This will work with simple filters on one field, what about more?

Advanced Filtering

As I said earlier, a manual approach handling multiple fields and multiple operators will turn out to be a LOT of code.

Imagine you want to apply the following filter:

(Product.Brand == "Nike" || Product.Brand == "Adidas")
&& (Product.Price >= 20 && Product.Price <= 100)
&& Product.Enabled

Using DynamicExpressions.NET, you can do it like this:

Of course, all the fields, values and operators can be provided by a user/frontend and it'll just work! The DynamicFilterBuilder lets you build complicated filters, which gives you everything you need for a fully dynamic filtering system!

As with all the other examples, the generated Expression Tree matches closely the one generated with lambdas, so you don't even have to worry about performance.

How does it work?

Let's take the example of the GetPropertyGetter method, used in the sorting example:

Here's what the code does, starting from line number 6:

  1. Create a ParameterExpression, which represents an instance, e.g. a product.
    • p.
  2. Create a MemberExpression, which represents the property that we want to access (it can be nested, e.g. Product.Category.Name).
    • p.Price.
  3. Convert the value of the property above to object, so that it can be used anywhere.
    • (object)p.Price.
  4. Create a lambda that uses all of the above.
    • p => (object)p.Price.

Expression Trees are a very powerful feature in C# that can be used in a lot of scenarios to generate performant code (expressions) at runtime!

Conclusion

All the examples that I showed in this blog post were about a Product entity. What if you want to be able to sort and/or filter on multiple entities? You will need to write custom code/switch statements for every one of them, and it can quickly become tedious.

DynamicExpressions.NET is here to remove all that straightforward and boring code out of your way, so that you focus more on the things that matter!

I hope you had a good read, don't hesitate to leave a feedback!
See you soon.

Zanid Haytam Written by:

Zanid Haytam is an enthusiastic programmer that enjoys coding, reading code, hunting bugs and writing blog posts.