get property of inner object

2019-09-10 05:55发布

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

1条回答
Melony?
2楼-- · 2019-09-10 06:25

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.

查看更多
登录 后发表回答