Keep NULL rows last on Dynamic Linq Order By

后端 未结 4 1476
一向
一向 2021-02-14 00:28

I am using this snippet below for Ordering my Linq queries dynamically and works great. I am not great at reflection or complex linq queries but I need a way that when ascendin

4条回答
  •  北海茫月
    2021-02-14 00:50

    For dynamically constructed Order By expression like this list.OrderBy("NAME DESC").ToList(), you can use the following query helper extension method.

    Usage

    First of all, we check to make sure property name exists in the given Class. If we do not check, it'll throw run-time exception.

    Then we use use either OrderByProperty or OrderByPropertyDescending.

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

    Here is the real world usage in my project at GitHub.

    Query Helper

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

提交回复
热议问题