Costruisci LambdaExpression per la proprietà nidificata dalla stringa

.net c# expression-trees lambda linq

Domanda

Sto cercando di creare un'espressione lambda per una proprietà nidificata in fase di esecuzione dal nome del propert. Fondamentalmente sto cercando di creare l'espressione lambda specificata da:

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

private static Expression CreateExpression<TEntity, TReturn>(Expression<Func<TEntity, TReturn>> expression)
{
    return (expression as Expression);
}

Con le classi:

class Foo
{
    public Bar myBar { get; set; }
}
class Bar
{
    public string name { get; set; }
}

Comunque tutto ciò che mi viene dato è il tipo di Foo e la stringa "myBar.name"

Se si trattasse di una proprietà normale come il solo bisogno del valore "myBar" potrei usare quanto segue:

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);
}

Tuttavia questo codice non funziona per le proprietà annidate e non sono sicuro di come creare LambdaExpression per eseguire il lavoro di foo.myBar.name .

Penso che sarà qualcosa di simile a questo:

GetExpression(Expression.Call(GetExpression(Foo, "myBar"), "name"))

Ma non riesco a capire come far funzionare tutto, o se c'è un modo migliore per farlo in fase di esecuzione.

Risposta accettata

Vuoi dire:

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);
}

Per esempio:

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
}

?



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché