从string构造用于嵌套属性的LambdaExpression

Sep*_*eph 35 .net c# linq lambda expression-trees

我试图从属性的名称在运行时为嵌套属性创建一个lambda表达式.基本上我正在尝试创建由以下指定的lambda表达式:

var expression = CreateExpression<Foo, object>(foo => foo.myBar.name);

private static Expression CreateExpression<TEntity, TReturn>(Expression<Func<TEntity, TReturn>> expression)
{
    return (expression as Expression);
}
Run Code Online (Sandbox Code Playgroud)

随着课程:

class Foo
{
    public Bar myBar { get; set; }
}
class Bar
{
    public string name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是我得到的只是Foo字符串的类型"myBar.name"

如果它是一个普通的属性,例如只需要该值,"myBar"那么我可以使用以下内容:

private static LambdaExpression GetPropertyAccessLambda(Type type, string propertyName)
{
    ParameterExpression odataItParameter = Expression.Parameter(type, "$it");
    MemberExpression propertyAccess = Expression.Property(odataItParameter, propertyName);
    return Expression.Lambda(propertyAccess, odataItParameter);
}
Run Code Online (Sandbox Code Playgroud)

但是,此代码不适用于嵌套属性,我不知道如何创建LambdaExpression来完成工作foo.myBar.name.

我认为这将是这样的:

GetExpression(Expression.Call(GetExpression(Foo, "myBar"), "name"))
Run Code Online (Sandbox Code Playgroud)

但我似乎无法弄清楚如何使它全部工作,或者如果有更好的方法在运行时这样做.

Mar*_*ell 94

你的意思是:

static LambdaExpression CreateExpression(Type type, string propertyName) {
    var param = Expression.Parameter(type, "x");
    Expression body = param;
    foreach (var member in propertyName.Split('.')) {
        body = Expression.PropertyOrField(body, member);
    }
    return Expression.Lambda(body, param);
}
Run Code Online (Sandbox Code Playgroud)

例如:

class Foo {
    public Bar myBar { get; set; }
}
class Bar {
    public string name { get; set; }
}
static void Main() {
    var expression = CreateExpression(typeof(Foo), "myBar.name");
    // x => x.myBar.name
}
Run Code Online (Sandbox Code Playgroud)

  • 真的很酷.Marc,有没有办法在嵌套列表中使用相同的行为?我的意思是类Foo {public List <Bar> myBar {get; 组; }} (3认同)
  • 很好的答案!+1 为清楚起见 (2认同)