I’m working on some expression tree code written by a colleague and am looking into the possibility of adding additional expressions. It currently supports: equals, not-equals, IsNull etc. I need to add something that will allow it to use a wildcard comparison similar to the SQL “Like” command or using regular expressions. At the moment the code parses an XML file and extracts the data which is then processed using code similar to the line shown below. This is an example of the “Equal” expression. “callExp” is a MemberExpression that basically holds the field name of my table (Entities) and GetConstantExpression gets details about the data I am comparing.
xRet = Expression.MakeBinary(ExpressionType.Equal, callExp, GetConstantExpression(element.Element("Value"), callExp.Type));
What I’m after is a way to create an “Expression” that is similar to the “Like” command. Can this be done using a few lines similar to above or is this going to be more complex? Any good resources that could help in this area?
==================================================================================
New code based on feedback:
I was looking at some examples and tried the following which I was hoping would create me an Expression. It gives me the error shown below. Am I going in the right direction to create a “StartsWith” expression? _entityExp is a ParameterExpression reference to MyClass.
ParameterExpression p = Expression.Parameter(_entityExp.Type, "entity");
MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
var containsMethod开发者_StackOverflowExp = Expression.Call(p, method, Expression.Constant("root"), p);
Method 'Boolean StartsWith(System.String)' declared on type 'System.String' cannot be called with instance of type 'MyClass'
Expression trees can only represent the same sort of functionality as you get in .NET languages - method calls, property evaluation etc.
The closest you normally get to "like" is to call string.StartsWith
, string.EndsWith
or string.Contains
. If you want to deal with regular expressions instead, you might want to use Regex.IsMatch
instead. Either way, this is something which is encapsulated in methods rather than in the "language" of expression trees itself.
Without knowing more about how your expression trees are consumed, it's hard to say exactly what you should do. You could create your own "Like" method which the consumer would notice and handle appropriately, for example... or you could use the existing string/regex methods.
Use Contains, startswith or endswith for like
We can create as below.
Expression.Call(memberExpression, typeof(string).GetMethod("Contains", new[] { typeof(string) }), constantExpression);
Expression.Call(memberExpression, typeof(string).GetMethod("EndsWith", new[] { typeof(string) }), constantExpression);
Expression.Call(memberExpression, typeof(string).GetMethod("StartsWith", new[] { typeof(string) }), constantExpression);
精彩评论