How to construct Order By Expression dynamically in Entity Framework?

前端 未结 2 445
盖世英雄少女心
盖世英雄少女心 2020-11-30 05:39

I used the following methods to construct Order By Expression. Original Source

It is really slick. The downside is it only works if Property is

2条回答
  •  情话喂你
    2020-11-30 06:39

    I found a solution with the help of Jon Skeet's old answer.

    public static class QueryHelper
    {
        private static readonly MethodInfo OrderByMethod =
            typeof (Queryable).GetMethods().Single(method => 
            method.Name == "OrderBy" && method.GetParameters().Length == 2);
    
        private static readonly MethodInfo OrderByDescendingMethod =
            typeof (Queryable).GetMethods().Single(method => 
            method.Name == "OrderByDescending" && method.GetParameters().Length == 2);
    
        public static bool PropertyExists(this IQueryable source, string propertyName)
        {
            return typeof(T).GetProperty(propertyName, BindingFlags.IgnoreCase |
                BindingFlags.Public | BindingFlags.Instance) != null;
        }
    
        public static IQueryable OrderByProperty(
           this IQueryable source, string propertyName)
        {
            if (typeof (T).GetProperty(propertyName, BindingFlags.IgnoreCase | 
                BindingFlags.Public | BindingFlags.Instance) == null)
            {
                return null;
            }
            ParameterExpression paramterExpression = Expression.Parameter(typeof (T));
            Expression orderByProperty = Expression.Property(paramterExpression, propertyName);
            LambdaExpression lambda = Expression.Lambda(orderByProperty, paramterExpression);
            MethodInfo genericMethod = 
              OrderByMethod.MakeGenericMethod(typeof (T), orderByProperty.Type);
            object ret = genericMethod.Invoke(null, new object[] {source, lambda});
            return (IQueryable) ret;
        }
    
        public static IQueryable OrderByPropertyDescending(
            this IQueryable source, string propertyName)
        {
            if (typeof (T).GetProperty(propertyName, BindingFlags.IgnoreCase | 
                BindingFlags.Public | BindingFlags.Instance) == null)
            {
                return null;
            }
            ParameterExpression paramterExpression = Expression.Parameter(typeof (T));
            Expression orderByProperty = Expression.Property(paramterExpression, propertyName);
            LambdaExpression lambda = Expression.Lambda(orderByProperty, paramterExpression);
            MethodInfo genericMethod = 
              OrderByDescendingMethod.MakeGenericMethod(typeof (T), orderByProperty.Type);
            object ret = genericMethod.Invoke(null, new object[] {source, lambda});
            return (IQueryable) ret;
        }
    }
    

    Usage

    string orderBy = "Name";
    if (query.PropertyExists(orderBy))
    {
       query = query.OrderByProperty(orderBy);
       - OR - 
       query = query.OrderByPropertyDescending(orderBy);
    }
    

提交回复
热议问题