Dynamic LINQ Expression with compund Criteria
//an example lambda expression with compound criteria:
var result = _people.Where(person => person.FirstName ==
"John" || person.Address.City == "Paoli" ).ToList();
//Create parameter expression
var parameterExpression =
Expression.Parameter(Type.GetType(
"ExpressionTreeTests.Person"), "person");
//Create constant to compare
var constant = Expression.Constant("John");
//The expression constant has to be compared to some property.
//The code in the next snippet creates a property expression.
//Note that the parameter expression created earlier is used to validate the property.
//If the property name passed as a string isn't found for the specified type, an error is thrown.
var property = Expression.Property(parameterExpression,
"FirstName");
//Next, you need to bring the expression constant and property together.
//In this case, you wish to test whether or not a property is equal to a string constant.
//The following code brings those two expressions together:
var expression = Expression.Equal(property, constant);
Expression property2 = parameterExpression;
//Next, you need to build up the second expression.
//This one is a bit more complicated because the City property is a member of an object that is, in turn, a member of the Person class:
//you have to traverse the hierarchy in order to validate nested properties:
foreach (var member in "Address.City".Split('.'))
{
property2 = Expression.PropertyOrField(property2, member);
}
//With the property expression resolved, you can now join it to the constant:
constant = Expression.Constant("Paoli");
var expression2 = Expression.Equal(property2, constant);
//The next step involves joining the two expressions:
expression = Expression.Or(expression, expression2);
//Once an expression has been created, you can create a lambda expression.
//The next code snippet accomplishes that task:
var lambda = Expression.Lambda<Func<Person,
bool>>(expression, parameterExpression);
var compiledLambda = lambda.Compile();
var result = _people.Where(compiledLambda).ToList();
//The following illustrates the generated lambda:
//{person => ((person.FirstName == "John") Or
// (person.Address.City == "Paoli"))}