Expression<Func> issue
I'm hoping t开发者_C百科o explain this clearly and concisely. I've got an expression:
Expression<Func<TObject, TProperty>> expression
that I'm trying to get the property name from. All is fine and dandy 'UNTIL', a convert expression is encountered (in the GetPropertyName method - this is where i want to sort the issue) i.e. normal properties may come out as {e =>e.EmployeeID}
but in a few cases, I'm getting a result of {e => Convert(e.EmployeeID)}
. This in effect means that I can't discern the correct property name (i don't want to parse for exceptions such as Convert() etc).
How can I cleanly extract the expression name as a property. Below is the code I'm using, so feel free to tamper with that:
public static class ExpressionExtensions
{
public static string GetPropertyName<TObject, TProperty>(
this Expression<Func<TObject, TProperty>> expression) where TObject : class
{
if (expression.Body.NodeType == ExpressionType.Call)
{
MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
string name = ExpressionExtensions.GetPropertyName(methodCallExpression);
return name.Substring(expression.Parameters[0].Name.Length + 1);
}
return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
}
private static string GetPropertyName(MethodCallExpression expression)
{
MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression;
if (methodCallExpression != null)
{
return GetPropertyName(methodCallExpression);
}
return expression.Object.ToString();
}
}
and I'm invoking it as so:
string propertyName = expression.GetPropertyName();
// which ideally should return a value of EmployeeID or ReportsTo
// as per the usage example below
and this bubbles up to some arbitary usage such as:
var tree = items2.AsHierarchy(e => e.EmployeeID, e => e.ReportsTo);
Hope this gives enough info to get me off the noose!!
cheers
You should have a "convert" node in your expression tree, so you should test the node for nodetype "convert", then if true go one level deeper before casting to string. Try something like this:
public static string GetMemberName<TSource,TMember>(this Expression<Func<TSource,TMember>> memberReference)
{
MemberExpression expression = memberReference.Body as MemberExpression;
if (expression == null)
{
UnaryExpression convertexp = memberReference.Body as UnaryExpression;
if(convertexp!=null)
expression = convertexp.Operand as MemberExpression; ;
}
if(expression==null)
throw new ArgumentNullException("memberReference");
return expression.Member.Name;
}
Have you got an example of an {e => Convert(e.EmployeeID)}
operation?
I would guess the Convert
is a boxing operation, i.e. it's taking a value type (presumably an int
?) and converting to object
. If so, and converting from int
to object
is the right thing to do, the Convert
is unavoidable; you should work around it in your GetPropertyName
method.
精彩评论