0

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.

0

1 Answer 1

0

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;
    }
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.