Neither the question nor the answer is the same as the question "Convert Linq expression “obj => obj.Prop†into “parent => parent.obj.Propâ€". The only duplicate I've found on here lately is the number of duplicate mods with control issues.
I'm attempting to make a extension method for Entity Framework that will add a "Contains" call on a field if the given value is not null or whitespace. It's out of pure laziness of not wanting all the if statement checks for null or whitespace.
I want to be able to use it like this:
var qry = MyDb.Redacteds.OrderBy(a=>a.RedactedDate);
qry = qry.WhereContains(a => a.RedactedName, txtRedactedName.Text);
I've come up with this, but obviously the Invoke causes an issue with EF. What's the trick to using the result of a lambda when building an expression?
// create
// ent => exp(ent).Contains(s)
public static IQueryable<T> WhereContains<T>(this IQueryable<T> qry, Expression<Func<T, string>> exp, string s)
{
if (!string.IsNullOrWhiteSpace(s))
{
s = s.Trim();
var param = Expression.Parameter(typeof(T), "ent");;
var call = Expression.Invoke(exp, param); // <-= HERE
var body = Expression.Call(call, typeof(string).GetMethod("Contains", new[] { typeof(string) }), Expression.Constant(s));
var lambda = Expression.Lambda<Func<T, bool>>(body, param);
qry = qry.Where(lambda);
}
return qry;
}
If it was simply a delegate instead of a lambda, the return could simple be:
ent => exp(ent).Contains(s)
That's what I'm looking to do.
You want to grab the parameter off the lambda and use the body as the expression. You aren't using it as a lambda at all - you are picking the expression tree and parameters out of the lambda.
// create
// ent => exp(ent).Contains(s)
public static IQueryable<T> WhereContains<T>(this IQueryable<T> qry, Expression<Func<T, string>> exp, string s)
{
if (!string.IsNullOrWhiteSpace(s))
{
s = s.Trim();
//HERE GRAB THE PARAMETER
var param = exp.Parameters[0];
//HERE JUST USE EXP.BODY
var body = Expression.Call(exp.Body, typeof(string).GetMethod("Contains", new[] { typeof(string) }), Expression.Constant(s));
var lambda = Expression.Lambda<Func<T, bool>>(body, param);
qry = qry.Where(lambda);
}
return qry;
}