Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# Expression Lambda to Func<T> from string

I try to implement e dynamic Funx expression from string

Expression<Func<CustomerDto, object>> expr = (src) => src.Customer.Id;
Func<CustomerDto, object> delg = expr.Compile();
var id = delg.Invoke(customerListDtos[0]);

and return the id (es. 123)

So now I try to create expression from string

    public Expression<Func<T, object>> GetLambda<T>(string property)
    {

        var param = Expression.Parameter(typeof(T), "p");
        Expression body = param;
        foreach (var member in property.Split('.'))
        {
            body = Expression.PropertyOrField(body, member);
        }
        //return Expression.Lambda(body, param);

        //Expression parent = Expression.Property(param, property);
        Expression parent = Expression.Lambda(body, param);
        //if (!parent.Type.IsValueType)
        //{
        //    return Expression.Lambda<Func<T, object>>(parent, param);
        //}
        var convert = Expression.Convert(parent, typeof(object));
        return Expression.Lambda<Func<T, object>>(convert, param);
    }

So if I call the result from GetLambda the output is not 123 but is

 var data = GetLambda<CustomerDto>("Customer.Id");
 Func<CustomerDto, object> g = data.Compile();
 var id = g(customerListDtos[0]);

the result is

{Method = {Int64 lambda_method(System.Runtime.CompilerServices.Closure, ef.Customer.CustomerDto)}}
like image 591
andmattia Avatar asked Jan 05 '23 13:01

andmattia


1 Answers

You are calling Expression.Labmda twice, essentially wrapping one func into another. Try this instead:

public static Expression<Func<T, object>> GetLambda<T>(string property) {
    var param = Expression.Parameter(typeof(T), "p");
    Expression body = param;
    foreach (var member in property.Split('.')) {
        body = Expression.PropertyOrField(body, member);
    }
    var convert = Expression.Convert(body, typeof(object));
    return (Expression<Func<T, object>>) Expression.Lambda(convert, param);
}
like image 102
Evk Avatar answered Jan 07 '23 03:01

Evk