它似乎你想要嵌套類型,嘗試這樣做。
在這種情況下,您需要的是一個可執行表達式,它將訪問該屬性的包含對象(例如,獲取源對象的Docs屬性或源對象的Docs屬性的Customer屬性)。您還需要目標屬性的PropertyInfo(例如ID)。並且您希望屬性訪問器和PropertyInfo具有相同的表達式。
這並不難。它不需要像最初那樣需要一堆目標對象和PropertyInfos。首先以正常方式從嵌套目標存儲PropertyInfo:
targetPropertyInfo = targetExpression.AsPropertyInfo();
這使我們可以訪問ID。然後將表達式從原始來源 - .Docs或.Customer.ID中檢索包含該屬性的對象的路徑。表達式樹中,這是它包含根到原始參數的表達式:
if (targetExpression.Body.NodeType == ExpressionType.MemberAccess)
{
MemberExpression memberExpression = targetExpression.Body as MemberExpression;
if (memberExpression.Expression.NodeType != ExpressionType.Parameter)
{
ParameterExpression parameter = GetParameterExpression(memberExpression.Expression);
if (parameter != null)
{
_targetExpression = Expression.Lambda(memberExpression.Expression, parameter);
}
}
}
關鍵線是包含Expression.Lambda所述一個()。父表達式是一個MemberExpression(例如model.Docs.Customer),它本身不可執行。您無法編譯MemberExpression並在對象上執行以獲取成員,因爲表達式需要知道它執行的參數。
Expression.Lambda創建針對提供目標參數的編譯,可執行的表達 - 這是我們已經從原始表達式的「模式」有,我們可以找到任何級別的嵌套:
private ParameterExpression GetParameterExpression(Expression expression)
{
while (expression.NodeType == ExpressionType.MemberAccess)
{
expression = ((MemberExpression)expression).Expression;
}
if (expression.NodeType == ExpressionType.Parameter)
{
return (ParameterExpression)expression;
}
return null;
}