Multiple Conditions in Lambda Expressions at runtime C#
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")
开发者_C百科
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
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.
精彩评论