get property of inner object
Asked Answered
A

1

0

Hi I am trying to use that code to get property User.Email of customer that contains User. but its an object (User of type User) so it throws exception. what should i fix?

public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string SortField, bool Ascending)
    {
        if (!string.IsNullOrWhiteSpace(SortField))
        {
            var param = Expression.Parameter(typeof (T), "p");
            var prop = Expression.Property(param, SortField);
            var exp = Expression.Lambda(prop, param);
            string method = Ascending ? "OrderBy" : "OrderByDescending";
            Type[] types = new Type[] {q.ElementType, exp.Body.Type};
            var mce = Expression.Call(typeof (Queryable), method, types, q.Expression, exp);
            return q.Provider.CreateQuery<T>(mce);
        }
        else
        {
            return q;
        }
    }
Autecology answered 22/12, 2015 at 12:39 Comment(0)
M
0

You need to pass a property path to the function (like "User.Email") and account for that inside, like this

public static IQueryable<T> OrderByField<T>(this IQueryable<T> source, string sortField, bool ascending)
{
    if (string.IsNullOrWhiteSpace(sortField)) return source;
    var item = Expression.Parameter(typeof(T), "item");
    Expression member = null;
    foreach (var memberName in sortField.Split('.'))
        member = Expression.PropertyOrField(member ?? item, memberName);
    var selector = Expression.Lambda(member, item);
    var method = ascending ? "OrderBy" : "OrderByDescending";
    var types = new [] { source.ElementType, selector.Body.Type };
    var expression = Expression.Call(typeof(Queryable), method, types, source.Expression, selector);
    return source.Provider.CreateQuery<T>(expression);
}

The essential part is

    var item = Expression.Parameter(typeof(T), "item");
    Expression member = null;
    foreach (var memberName in sortField.Split('.'))
        member = Expression.PropertyOrField(member ?? item, memberName);

which starts from the expression parameter and builds an accessor for each member specified in the path.

Miraculous answered 6/1, 2016 at 21:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.