[英]Expression tree for a member access of depth > 1
public class Job
{
public string Name { get; set; }
public int Salary { get; set; }
}
public class Employee
{
public string Name { get; set; }
public Job Job { get; set; }
}
如果我想創建對Employee.Name的成員訪問的表達式樹,這就是我要做的:
var param = Expression.Parameter(type, "x");
var memberAccess = Expression.PropertyOrField(param, memberName);
return Expression.Lambda<Func<TModel, TMember>>(memberAccess, param);
成員對Employee.Job.Salary的訪問權限相當於什么?
你需要:
var jobProperty = Expression.PropertyOrField(param, "Job");
var salaryProperty = Expression.PropertyOrField(jobProperty, "Salary");
基本上,您將從評估x.Job
的結果中獲取Salary
屬性。
如果您需要以編程方式進行此操作,則需要以下內容:
Expression expression = Expression.Parameter(type, "x");
foreach (var property in properties.Split('.'))
{
expression = Expression.PropertyOrField(expression, property);
}
最好的方法是創建擴展, 如下所示 :
public static class ExpressionExtensions
{
/// <summary>
/// create expression by property name
/// </summary>
/// <typeparam name="TModel"></typeparam>
/// <param name="propertyName">
/// <example>Urer.Role.Name</example>
/// </param>
/// <returns></returns>
public static Expression<Func<TModel, dynamic>> CreateExpression<TModel>(this string propertyName) {
Type currentType = typeof (TModel);
ParameterExpression parameter = Expression.Parameter(currentType, "x");
Expression expression = parameter;
int i = 0;
List<string> propertyChain = propertyName.Split('.').ToList();
do {
System.Reflection.PropertyInfo propertyInfo = currentType.GetProperty(propertyChain[i]);
currentType = propertyInfo.PropertyType;
i++;
if (propertyChain.Count == i)
{
currentType = typeof (object);
}
expression = Expression.Convert(Expression.PropertyOrField(expression, propertyInfo.Name), currentType);
} while (propertyChain.Count > i);
return Expression.Lambda<Func<TModel, dynamic>>(expression, parameter);
}
}
您不能每次都將Convert()轉換為typeof(object),因為System.Object不具有您的類型具有的屬性(例如示例中的Name或Salary)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.