Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Conditions in Lambda Expressions at runtime C#

Tags:

c#

lambda

I would like to know how to be able to make an Expression tree by inputting more than one parameter

Example:

dataContext.Users.Where(u => u.username == "Username" && u.password == "Password")

At the moment the code that I did was the following but would like to make more general in regards whether the condition is OR or AND

public Func<TLinqEntity, bool> ANDOnlyParams(string[] paramNames, object[] values)
    {
        List<ParameterExpression> paramList = new List<ParameterExpression>();
        foreach (string param in paramNames)
        {
            paramList.Add(Expression.Parameter(typeof(TLinqEntity), param));
        }

        List<LambdaExpression> lexList = new List<LambdaExpression>();
        for (int i = 0; i < paramNames.Length; i++)
        {
            if (i == 0)
            {
                Expression bodyInner = Expression.Equal(
                                    Expression.Property(
                                        paramList[i], paramNames[i]),
                                        Expression.Constant(values[i]));
                lexList.Add(Expression.Lambda(bodyInner, paramList[i]));
            }
            else
            {
                Expression bodyOuter = Expression.And(
                                    Expression.Equal(
                                    Expression.Property(
                                    paramList[i], paramNames[i]),
                                    Expression.Constant(values[i])),
                                    Expression.Invoke(lexList[i - 1], paramList[i]));
                lexList.Add(Expression.Lambda(bodyOuter, paramList[i]));
            }
        }

        return ((Expression<Func<TLinqEntity, bool>>)lexList[lexList.Count - 1]).Compile();
    }

Thanks

like image 243
Ryan Avatar asked Mar 21 '10 11:03

Ryan


1 Answers

Expression.And is the wrong thing to use here, it's the bitwise and. You want AndAlso.

It seems like you aside from that you already know the mechanics of how to build the expression tree. So what you're really asking is how can you let the caller of your building-method specify a more complicated, flexible way of combining different conditions.

Ultimately for true flexibility you need a mini query language. Parse the language to build the expression tree.

In the short term, you might get by with something much simpler: a list of primitive expressions and a bool flag to say whether they should be combined with && or ||.

Update - I notice you're actually compiling the resulting expression into a real delegate. This makes me wonder why you're doing this the hard way in the first place. Why not just write the expression as a lambda, as in your initial example? (If you're using Linq to SQL or EF, you shouldn't be compiling the expression anyway.)

Update 2 - What you probably need is Dynamic Linq.

like image 99
Daniel Earwicker Avatar answered Nov 15 '22 05:11

Daniel Earwicker