I am going to create a more complex filtering system for this huge project of ours. One of the main predicates is the ability to pass comparisons through a string parameter. This is expressed as: "> 50" or "5-10" or "<123.2"
What I have (as an example for illustration)
ViewModel:
TotalCost (string) (value: "<50") Required (string) (value: "5-10")
EF Model:
TotalCost (double) Required(double)
The expression I would like to use:
model => model.Where(field => field.TotalCost.Compare(viewModel.TotalCost) && field.Required.Compare(viewModel.Required));
The expression I would like to get:
model => model.Where(field => field.TotalCost < 50 && field.Required > 5 && field.Required < 10);
Or something like this
However ... I do not know where to start. I narrowed it down to
public static Expression Compare<T>(this Expression<Func<T, bool>> value, string compare)
This may not be entirely correct, but thatβs all I have. The comparison constructor is not a problem, it is a simple bit. The hard part actually returns an expression. I have never tried returning expressions as function values. So basically what I need to save is a field and returns a comparison expression, to a large extent.
Any help ?: X
Update:
Alas, this does not solve my problem. Maybe because I have been in the last 23 hours, but I have no idea how to do this using the extension method. As I said, I would like ... basically a way to write:
var ex = new ExTest(); var items = ex.Repo.Items.Where(x => x.Cost.Compare("<50"));
The way I configured this function (possibly completely wrong)
public static Expression<Func<decimal, bool>> Compare(string arg) { if (arg.Contains("<")) return d => d < int.Parse(arg); return d => d > int.Parse(arg); }
There is no "this -something-value" for comparison in the first place, and I have not yet been able to figure out how to get the ability to enter an expression ... as for ReSharper, this involves me converting to boolean instead ...
My head is full of fluff at the moment ...
Update 2:
I managed to find a way to have a code snippet that works in a memory repository in a console application. I have yet to try it with 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); }
However, I doubt very much that what I am after
Update 3:
That's right, after you went down and looked again at lambda expressions, before the last answer I came up with something similar to the following: it does not fill out the exact requirements of "Compare ()", but "overload" is -ish 'Where is the method:
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); }
However, despite my eyes, everything seems logical, I get an exception at runtime:
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)
This is obviously the culprit's line:
var lambda = Expression.Lambda<Func<T, bool>>(Expression.LessThan(predicate.Body, Expression.Constant(double.Parse(50.ToString()))));
I am very close to a solution. If I can get this error from my back, I believe that EF should be able to translate this into SQL. Otherwise ... well, the last answer will probably go.