Я собираюсь создать более сложную систему фильтрации для этого огромного нашего проекта. Одним из основных предикатов является возможность передавать сравнения через строковый параметр. Это выражается в следующем виде: "> 50" или "5-10" или "< 123,2"Метод расширения, возвращающий выражение лямбда с помощью сравнения
То, что я (в качестве примера для иллюстрации)
ViewModel:
TotalCost (string) (value: "<50")
Required (string) (value: "5-10")
EF Модель:
TotalCost (double)
Required(double)
Expression, что я хотел бы использовать:
model => model.Where(field => field.TotalCost.Compare(viewModel.TotalCost) && field.Required.Compare(viewModel.Required));
Expression, что я хотел бы получить:
model => model.Where(field => field.TotalCost < 50 && field.Required > 5 && field.Required < 10);
Или что-то похожее на этот
Однако ... Я понятия не имею, с чего начать. Я сузил его до
public static Expression Compare<T>(this Expression<Func<T, bool>> value, string compare)
Это может быть и не совсем правильно, но это все, что у меня есть. Конструктор сравнения не проблема, это легкий бит. Жесткая часть фактически возвращает выражение. Я никогда не пробовал возвращать выражения как значения функций. Так что в основном то, что мне нужно сохранить, является полем и возвращает выражение сравнения, в значительной степени.
Любая помощь? : Х
Update:
Увы это не решает мою проблему. Может быть, потому, что я был в течение последних 23 часов, но у меня нет ни малейшего понятия о том, как сделать это методом расширения. Как я уже сказал, что я хотел бы ... в основном способ написания:
var ex = new ExTest();
var items = ex.Repo.Items.Where(x => x.Cost.Compare("<50"));
Так я в форме, что функция (возможно, совершенно неправильно) является
public static Expression<Func<decimal, bool>> Compare(string arg)
{
if (arg.Contains("<"))
return d => d < int.Parse(arg);
return d => d > int.Parse(arg);
}
Это с отсутствующим " this -something-value ", чтобы сравнить на первом месте, и мне еще не удалось выяснить, как получить возможность ввода выражения ... что касается ReSharper, он предлагает мне преобразовать его в boolean вместо этого ...
Моя голова пуха на данный момент ...
Update 2:
мне удалось выяснить способ, чтобы иметь кусок кода, который работает в хранилище памяти на консольное приложение. Я еще должен попробовать его с Entity Framework.
public static bool Compare(this double val, string arg)
{
var arg2 = arg.Replace("<", "").Replace(">", "");
if (arg.Contains("<"))
return val < double.Parse(arg2);
return val > double.Parse(arg2);
}
Однако, я очень сомневаюсь, что это то, что я после
Update 3:
справа, после того, как сесть и снова просматривал лямбда-выражений, до последнего ответа, я пришел с чем-то вроде следующего, он не заполняет точные требования «Compare()», но это «перегрузка-иш». Где метод:
public static IQueryable<T> WhereExpression<T>(this IQueryable<T> queryable, Expression<Func<T, double>> predicate, string arg)
{
var lambda =
Expression.Lambda<Func<T, bool>>(Expression.LessThan(predicate.Body, Expression.Constant(double.Parse(50.ToString()))));
return queryable.Where(lambda);
}
Однако, несмотря на мои глаза, все, казалось логичным, я получаю исключение во время выполнения:
System.ArgumentException was unhandled
Message=Incorrect number of parameters supplied for lambda declaration
Source=System.Core
StackTrace:
at System.Linq.Expressions.Expression.ValidateLambdaArgs(Type delegateType, Expression& body, ReadOnlyCollection`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, String name, Boolean tailCall, IEnumerable`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, Boolean tailCall, IEnumerable`1 parameters)
at System.Linq.Expressions.Expression.Lambda[TDelegate](Expression body, ParameterExpression[] parameters)
Это является виновником линии, очевидно:
var lambda =
Expression.Lambda<Func<T, bool>>(Expression.LessThan(predicate.Body, Expression.Constant(double.Parse(50.ToString()))));
Я очень близок к решению. Если я смогу получить эту ошибку с моей спины, я считаю, что EF должен быть способен перевести это в SQL. В противном случае ... ну, последний ответ, вероятно, пойдет.
Я думаю, что ваша Update2 часть не будет выполняться с SQL Server (EF). Вы попробовали? –
Да, просто сделал. Как я думал, тбх. – NeroS