lundi 25 janvier 2021

How to retrieve a property of an object from a string?

In order to use it as a selector in a Grouping Clause at runtime, I want basically retrieve a property from an object T by passing its name. Example with this class:

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime Birthday { get; set; }
}

I want to use my method like this:


private void MyMethod(string propertyName)
{
    var lambda = GetLambdaExpression(propertyName);

    // The problem is to specify the Type at compile time...
    var selector = GetLambdaSelector<DateTime>(lambda); // Seems mandatory to convert LambdaExpression to Expression<Func<Person, T>> to use in a grouping clause
    
    var result = emps.GroupBy(
        selector.Compile(),
        p => p.Birthday,
        (key, g) => new { PersonName = key, = g.ToList() }).AsQueryable();
}

Here are methods statements :

        LambdaExpression GetLambdaExpression(string propertyName)
        {
            var type = typeof(Person); 

            var propertyInfo = type.GetProperty(propertyName);
            var propertyType = propertyInfo.PropertyType;

            var entityType = propertyInfo.DeclaringType;
            var parameter = Expression.Parameter(entityType, "entity");
            var property = Expression.Property(parameter, propertyInfo);
            var funcType = typeof(Func<,>).MakeGenericType(entityType, propertyInfo.PropertyType);
            var lambda = Expression.Lambda(funcType, property, parameter);
            return lambda;
        }

        Expression<Func<Person, T>> GetLambdaSelector<T>(LambdaExpression expression)
        {
            return (Expression<Func<Person, T>>)expression;
        }

I'm stuck because I want to resolve the type (DateTimein the example) at runtime and not at compile time.

So how to call this method with type resolve at runtime: GetLambdaSelector<?>(lambda); ?

Or maybe can I change the signature of LambdaExpression GetLambdaExpression(string propertyName) to Expression<Func<Person, T>> with reflection but I did not manage it for the moment. ?





Aucun commentaire:

Enregistrer un commentaire