В настоящее время я много работаю с выражениями, поэтому думаю, что смогу вам помочь.
Я только что создал собственный код для вас.
Код подтверждает, что вы добавляете свойства в свой отфильтрованный класс (Account) без необходимости изменения кода построения фильтра.
Код фильтрует строку Properties и использует ее для создания предиката.
public Func<Account, bool> GetPredicate(Parameters parameters)
{
var stringProperties = typeof(Parameters)
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(x => x.PropertyType == typeof(string));
var parameterExpression = Expression.Parameter(typeof(Account));
var notNullPropertyNameToValue = new Dictionary<string, string>();
BinaryExpression conditionExpression = null;
foreach (var stringProperty in stringProperties)
{
var propertyValue = (string)stringProperty.GetValue(parameters);
if (propertyValue != null)
{
var propertyAccessExpression = Expression.PropertyOrField(parameterExpression, stringProperty.Name);
var propertyValueExpression = Expression.Constant(propertyValue, typeof(string));
var propertyTestExpression = Expression.Equal(propertyAccessExpression, propertyValueExpression);
if (conditionExpression == null)
{
conditionExpression = propertyTestExpression;
}
else
{
conditionExpression = Expression.And(conditionExpression, propertyTestExpression);
}
}
}
//Just return a function that includes all members if no parameter is defined.
if (conditionExpression == null)
{
return (x) => true;
}
var lambdaExpression = Expression.Lambda<Func<Account, bool>>(conditionExpression, parameterExpression);
return lambdaExpression.Compile();
}
Возвращает типизированный предикат, который вы можете используйте, например, в Linq.
См. этот пример:
void Main()
{
var customers = new List<Account>()
{
new Account()
{
CustomerId = "1",
},
new Account()
{
CustomerId = "2",
}
};
var predicate = GetPredicate(new Parameters() { CustomerId = "1" });
customers.Where(predicate);
}
Если вам нужна помощь, не стесняйтесь спрашивать!