from a Lambda Expression.
With regards to Expression Trees I know the common practice
is to build from the bottom up but reversed when coded i.e.
ParameterExpression 1st
MemberExpression 2nd
ConstantExpression 3rd
BinaryExpression 4th
LambdaExpression 5th - for executing and compiling to a delegate.
With expressions 1-4 being used to form the Body of the Expression Tree.
My question is from the code example below I cant seem
to see how the Expressions 1-4 are being used to form the Body?
It looks like only some are used?
Regards,
public static class PredicateBuilder
{private static readonly MethodInfo asNonUnicodeMethodInfo =
typeof(EntityFunctions).GetMethod("AsNonUnicode");
private static readonly MethodInfo stringEqualityMethodInfo =
typeof(string).GetMethod("op_Equality");
public static Expressionbool>> ContainsNonUnicodeString (
IEnumerable<string> source, Expressionstring>> expression)
{if (source == null) throw new ArgumentNullException("source");
if (expression == null) throw new ArgumentNullException("expression");
Expression predicate = null;foreach (string value in source)
{var fragment = Expression.Equal(
expression.Body,
Expression.Call(null, asNonUnicodeMethodInfo,
Expression.Constant(value, typeof(string))),
false, stringEqualityMethodInfo);
if (predicate == null)
{predicate = fragment;
}
else {predicate = Expression.OrElse(predicate, fragment);
}
}
return Expression.Lambdabool>>(predicate,
((LambdaExpression)expression).Parameters);
}
}
VulpesPosted May 15, 2013, 10:05 AM
I haven't had time to test it but it seems to be building and returning an expression tree which provides a predicate to test whether or not a collection of strings contains a non-unicode string - how it cannot do, I don't know as all strings in .NET are unicode!
One of the parameters is itself an expression tree and the whole thing is very general.
You can see some of the usual elements in there such as Expression.Constant which holds the value of the current string in the collection and Expression.OrElse which OR's the individual predicates together.
However, no ParameterExpression is being built. Instead the 'expression' argument's Parameters collection is being passed through to the lambda expression in the final return statement:
return Expression.Lambda
Expression tree code is never easy to understand (even worse than reflection) and it's probably best not to expect it to conform to any particular sequence of steps when trying to read it.
VulpesPosted May 15, 2013, 6:37 PM
Anyway, I see now what they mean by non-unicode string - they're talking about the type of column in the underlying database which need not, of course, be unicode.
Guest UserPosted May 15, 2013, 10:44 AM
the usage of the code would be as follows:-
var values = new[] { "a", "b", "c" };
var q = context.Customers.Where( PredicateBuilder.ContainsNonUnicodeString