Dynamically Building and Filtering Lambda Expressions in C#
Lambda expressions are a powerful feature in C# that allows developers to create anonymous functions on the fly. They are often used with LINQ queries to provide concise, readable code for manipulating and filtering data. However, what if you need to construct a lambda expression dynamically based on user input? In this tutorial, we will walk through the process of creating dynamic lambda expressions and using them to filter a list of records in C#.
Access to the GitHub repo : Link
Step 1: Defining the Record and Filter classes
Before we dive into the dynamic lambda expressions, let’s first define two classes: Record
and Filter
. The Record
class represents an individual record with properties Id
, Name
, and Age
, while the Filter
class represents a filter condition with properties ColumnName
and Value
.
class Record
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
class Filter
{
public string ColumnName { get; set; }
public string Value { get; set; }
}
Step 2: Building the dynamic filter expression
In the Main
method, we will create a list of Record
objects and a list of Filter
objects. Then, we will create a parameter expression for the input data of type Record
.
var data = new List<Record>
{
new Record { Id = 1, Name = "Rashad", Age = 25 },
new Record { Id = 2, Name = "Elvin", Age = 30 },
new Record { Id = 3, Name = "Ceyhun", Age = 35 },
new Record { Id = 4, Name = "Aysel", Age = 40 },
};
var filters = new List<Filter>
{
new Filter { ColumnName = "Name", Value = "E" },
new Filter { ColumnName = "Age", Value = "30" },
};
var parameter = Expression.Parameter(typeof(Record), "record");
Next, loop through each Filter
object in filters
and build a dynamic filter expression based on the specified filter conditions.
Expression filterExpression = null;
foreach (var filter in filters)
{
var property = Expression.Property(parameter, filter.ColumnName);
var constant = Expression.Constant(filter.Value);
Expression comparison;
if (property.Type == typeof(string))
{
comparison = Expression.Call(property, "Contains", Type.EmptyTypes, constant);
}
else
{
//Convert values based on property type
constant = Expression.Constant(Convert.ToInt32(filter.Value));
comparison = Expression.Equal(property, constant);
}
filterExpression = filterExpression == null
? comparison
: Expression.And(filterExpression, comparison);
}
Important: We have to convert values based on property type in
foreach
loop.
Step 3: Creating and compiling the lambda expression
Now, create a lambda expression using the filter expression and the parameter expression. Compile the lambda expression into a delegate of type Func<Record, bool>
.
var lambda = Expression.Lambda<Func<Record, bool>>(filterExpression, parameter);
var func = lambda.Compile();
Step 4: Filtering the data and displaying the results
Finally, use the Where
extension method from LINQ to filter the input data using the delegate. Print the filtered records to the console.
var filteredData = data.Where(func);
foreach (var record in filteredData)
{
Console.WriteLine($"Id: {record.Id}, Name: {record.Name}, Age: {record.Age}");
}
Conclusion
In this tutorial, we demonstrated how to create dynamic lambda expressions in C# to filter a list of records based on user-defined filter conditions. This technique can be applied to any set of properties and conditions, making it a powerful tool for building flexible and reusable filtering logic in your applications.
GitHub repo : Link