Как говорится в названии, я пытаюсь создать дерево выражений для cheking, если какой-либо элемент в списке строки соответствуют строке объекта Book.Создание дерева выражений для List.Any (v => v.Contains (Book.Title.ToString()))
До сих пор я получил это:
private static Expression<Func<Books, bool>> GenerateListContainsLikeExpression(string propertyName, List<string> values)
{
var parameter = Expression.Parameter(typeof(Books), "b");
var listParameter = Expression.Parameter(typeof(string), "v");
var property = Expression.Property(parameter, propertyName);
var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).First(m => m.Name == "Any" && m.GetParameters().Count() == 2).MakeGenericMethod(typeof(string));
var toStringMethod = typeof(object).GetMethod("ToString");
var containsMethod = typeof(string).GetMethod("Contains");
var objectString = Expression.Call(property, toStringMethod);
var lambda = Expression.Call(listParameter, containsMethod, objectString);
var func = Expression.Lambda<Func<List<string>, bool>>(lambda, parameter);
var comparison = Expression.Call(anyMethod, Expression.Constant(values), func);
return Expression.Lambda<Func<Books, bool>>(comparison, parameter);
}
Но я получаю эту ошибку:
Expression of type 'System.Boolean' cannot be used for parameter of type 'System.Func
2[System.String,System.Boolean]' of method 'Boolean Any[String](System.Collections.Generic.IEnumerable
1[System.String], System.Func`2[System.String,System.Boolean])'
На этой линии:
var comparison = Expression.Call(anyMethod, Expression.Constant(values), lambda);
Я чувствую, что я просто нужен последний маленький бит.
Заранее спасибо :-)
EDIT: Для разъяснения. Я объясню немного более подробное, что мне нужно.
Мне нужно было классифицировать книги на основе некоторых свойств книг. В этом конкретном случае я передаю список строк функции. Мне нужно было проверить, содержалась ли какая-либо из этих строк в любом названии книг.
Итак, прежде всего, лямбда, с которой я считала нужным, была неправильной для начала. Это лямбда, что я на самом деле необходимое: b => values.Any(v => b.Title.ToString().Contains(v))
И вот окончательный код, который я закончил с:
private static Expression<Func<Books, bool>> GenerateListContainsLikeExpression(string propertyName, List<string> values)
{
var parameter = Expression.Parameter(typeof(Books), "b");
var listParameter = Expression.Parameter(typeof(string), "v");
var property = Expression.Property(parameter, propertyName);
var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).First(m => m.Name == "Any" && m.GetParameters().Count() == 2).MakeGenericMethod(typeof(string));
var toStringMethod = typeof(object).GetMethod("ToString");
var containsMethod = typeof(string).GetMethod("Contains");
var objectString = Expression.Call(property, toStringMethod);
var lambda = Expression.Call(objectString, containsMethod, listParameter);
var func = Expression.Lambda<Func<string, bool>>(lambda, listParameter);
var comparison = Expression.Call(anyMethod, Expression.Constant(values), func);
return Expression.Lambda<Func<Books, bool>>(comparison, parameter);
}
Ваш func, вероятно, не такой, как вы думаете, и, вероятно, прищурился. Любой метод расширения, поэтому вам нужно будет вызвать статический метод в своем выражении. Список должен быть списком книг? Похоже, это так, но, похоже, вы рассматриваете аргумент для функции Any func как самого списка, а не одну из книг в списке. Все выглядит неправильно ... Я думаю, что есть конвертер выражения ambda =>, который вы можете использовать, чтобы узнать, как работает материал ... lemme peek для него. – Will
Да, я думаю, вы можете просто пойти 'Expression> expr = x => x.Any (v => v.Contains (Book.Title.ToString())) ;; а затем изучить выражение в быстрой посмотреть окно, чтобы посмотреть, как оно построено. Опять же, я не знаю, что ваш «TInput» от лямбды в вашем названии. –
Will
Я отредактировал сообщение, чтобы вы могли увидеть полный метод. –