linq表达式根据属性名列表动态生成表达式< Func< T,object>>

zkure5ic  于 2023-09-28  发布在  其他
关注(0)|答案(1)|浏览(101)

给定一个类型T和一个字符串列表,这些字符串是T中的属性名,如{“prop 1”,“prop 2”}
我想生成一个像下面这样的表达式,它是一个动态对象:

Expression<Func<T, object>> in the format:  x => new {x.prop1, x.prop2}

我能够创建一个属性访问器,但不能确定表达式的动态类型。

private Func<T, int> BuildChildSelectorLambda(string idPropertyName) {

        ParameterExpression argParam = Expression.Parameter(typeof(T), "x");
        Expression selector = Expression.Property(argParam, typeof(T).GetProperty(idPropertyName));
    
        return  Expression.Lambda<Func<T,int>>(selector, argParam).Compile();
        //TODO: CACHE EXPRESSIONS
    }
yyyllmsg

yyyllmsg1#

为了创建这样的表达式,你需要有一个实际的类来创建一个示例。当你的代码显示为new{x.prop1, x.prop2}时,它实际上是声明了一个匿名类,这个类将与你的代码一起编译。如果你没有一个特定的类,你可能需要创建一个类似System.Reflection.EmitRoslyn的类。然后创建一个针对该类的初始化表达式。
或者,根据您要做的事情,您可以使用预定义的泛型类。例如,如果您只是试图创建一个表达式来传递给GroupBy LINQ方法,那么您创建的对象中的属性名称实际上并不重要。所以你可以创建一些像这样的类型:

class TargetTuple<T>{
    public T Prop1 {get; init;}
}
class TargetTuple<T1, T2>
{
    public T1 Prop1 { get; init; }
    public T2 Prop2 { get; init; }
}

然后构建一个表达式树,看起来更像这样:

(Expression<Func<Source, object>>)(x => new TargetTuple<string> { Prop1 = x.prop1 })

相关问题