I'm struggling to build an expression tree so I can dynamically do filtering on some data.
I have come up with this, but it fails at the var lambda =
line
foreach (var rule in request.Where.Rules)
{
var parameterExpression = Expression.Parameter(typeof(string), rule.Field);
var left = Expression.Call(parameterExpression, typeof(string).GetMethod("ToLower", Type.EmptyTypes));
var right = Expression.Constant(rule.Data.ToLower());
var method = typeof(string).GetMethod("Contains", new [] { typeof(string) });
var call = Expression.Call(left, method, right);
var lambda = Expression.Lambda<Func<T, bool>>(call, parameterExpression);
query = query.Where(lambda);
}
The var rule
has a Field (ex "Name") which I want to compare with the text in rule.Data
(ex 'tom'). So if T.Name.Contains("tom");
I want the query to include the record, otherwise, not.
The var query
is of type IQueryable<T>
EDIT: Finally got it working with this code:
foreach (var rule in request.Where.Rules)
{
var parameter = Expression.Parameter(typeof(T), "x");
var property = Expression.Property(parameter, rule.Field);
var value = Expression.Constant(rule.Data);
var type = value.Type;
var containsmethod = type.GetMethod("Contains", new[] { typeof(string) });
var call = Expression.Call(property, containsmethod, value);
var lambda = Expression.Lambda<Func<T, bool>>(call, parameter);
query = query.Where(lambda);
}
You are almost there, but your parameter expression should be of type T
, not String
, you are also missing the expression that is getting the property from type T
like name.
What you should roughly have is this
val -> Expression.Constant(typeof(string), rule.Field)
parameter -> Expression.Parameter(typeof(T), "p")
property -> Expression.Property(parameter, "PropertyName")
contains -> Expression.Call(property, containsmethod, val)
equals true -> Expression.True or equals, something like that
I am freehanding all of that, so it's likely somewhat different to be valid. The resulting expression should be something like this
p => p.Name.Contains(val)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With