C # как создать более сложное выражение .Any () - PullRequest
0 голосов
/ 23 января 2019

У меня есть этот массив фильтров, который имеет свойство Name, value и propertyType. На основе PropertyType я создаю Expression и, наконец, у меня есть список выражений, которые я затем агрегирую с помощью And.

return filter?
.Where(f => !string.IsNullOrEmpty(f.Value))?
.Select(f =>
{
  var parameter = Expression.Parameter(typeof(T), "item");
  var property = Expression.Property(parameter, PascalCase(f.PropertyName));

  Expression expression = null;

  if (f.Type == PropertyTypeEnum.String)
  {
      var toLowerMethod = typeof(string).GetMethod("ToLower", new Type[] { });
      var startsWithMethod = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
      var value = Expression.Constant(f.Value.ToLower());
      var loweredProperty = Expression.Call(property, toLowerMethod);

      expression = Expression.Call(loweredProperty, startsWithMethod, value);
   }
   else
   {
     var value = Convert.ChangeType(f.Value, property.Type);

     ConstantExpression constantExpression = Expression.Constant(value);
     expression = Expression.Equal(property, constantExpression);
   }

   return Expression.Lambda<Func<T, bool>>(expression, parameter);
 });

который я помещаю в Linq. Где и если тип перечисления является строкой, это выглядит так

.Where(x => x.ToLower().StartsWith(someString)).

Теперь у меня есть опция, где PropertyType - Array, и я хочу иметь это выражение

(x => x.Any(y => y.ToLower().StartsWith(someString)));

Но как именно я могу построить такое выражение?

1 Ответ

0 голосов
/ 23 января 2019

удалось заставить его работать. Это код внутри оператора case

var innerProperty = Expression.PropertyOrField(parameter, PascalCase(f.PropertyName));
var innerParameter = Expression.Parameter(typeof(string), "y");

var toLowerMethod = typeof(string).GetMethod(nameof(string.ToLower), new Type[] { });
var startsWithMethod = typeof(string).GetMethod(nameof(string.StartsWith), new[] { typeof(string) });
var value = Expression.Constant(f.Value.ToLower());
var loweredProperty = Expression.Call(innerParameter, toLowerMethod);
var innerExp = Expression.Call(loweredProperty, startsWithMethod, value);
var predicate = Expression.Lambda<Func<string, bool>>(innerExp, innerParameter);

expression = Expression.Call(typeof(Enumerable), "Any", new[] { typeof(string) }, innerProperty, predicate);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...