Я хочу создать динамические лямбда-выражения, чтобы можно было фильтровать список, используя набор параметров фильтрации.Это то, что у меня есть:
Выражение построено с использованием методов ниже, где T - тип объекта списка
public static Expression<Func<T, bool>> GetExpression<T>(IList<DynamicFilter> filters)
{
if (filters.Count == 0)
return null;
ParameterExpression param = Expression.Parameter(typeof(T), "t");
Expression exp = null;
if (filters.Count == 1)
exp = GetExpression<T>(param, filters[0]);
[...]
return Expression.Lambda<Func<T, bool>>(exp, param);
}
private static Expression GetExpression<T>(ParameterExpression param, DynamicFilter filter)
{
MemberExpression member = Expression.Property(param, filter.PropertyName);
ConstantExpression constant = Expression.Constant(filter.Value);
[...]
return Expression.Call(member, filterMethod, constant);
}
Затем я вызываю
List<Example> list = ...;
var deleg = ExpressionBuilder.GetExpression<Example>(dynFiltersList).Compile();
list = list.Where(deleg).ToList();
Это работает так же, как и ожидалось с объектом, который содержит только простые типы, но если внутри есть сложные типы, код больше не работает.Например, допустим, у меня есть член пользовательского типа Field внутри класса Example, а Field имеет строковое свойство Value.Если бы filter.PropertyName
было бы 'Field0' (типа Field), код работал бы просто отлично, но если бы у меня было 'Field0.Value', я бы получил очевидную ошибку, утверждая, что внутри нет свойства с именем 'Field0.Value'Пример класса.
Я попытался изменить метод построения выражений, например:
MemberExpression member = null;
if (filter.PropertyName.Contains('.'))
{
string[] props = filter.PropertyName.Split('.');
ParameterExpression param1 = Expression.Parameter(typeof(T).GetProperty(props[0]).PropertyType, "t1");
member = Expression.Property(param1, props[0]);
}
else
{
member = Expression.Property(param, filter.PropertyName);
}
, но затем я получил ошибку Lambda parameter not in scope
при компиляции выражения.Я вроде понимаю, почему я получаю эту ошибку, но я не знаю, как заставить это работать.
Суть в том, что мне нужно заставить метод построения выражений работать рекурсивно при формировании выражения MemberExpression.В конечном итоге мне нужно получить list = list.Where(deleg).ToList();
, который переводится в нечто подобное list = list.Where(obj => obj.Field0.Value == 'something').ToList();
Я только начал работать с выражениями, поэтому я не очень много знаю в этой области, но любая помощь будетоценил.
Спасибо