2012-09-05 17 views
2

排序我編寫了這個代碼,IQueryable<T>sortColumn列。我想擴展它,以便具有BirthDate列的值等於DateTime.Today的值的條目將排在第一位,但我無法找到或想到如何完成這項工作。使用Linq.Expressions.Expression

public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string sortColumn, bool asc) 
{ 
    var param = Expression.Parameter(typeof(T), "p"); 

    var prop = Expression.Property(param, sortColumn); 

    var exp = Expression.Lambda(prop, param); 

    string method = asc ? "OrderBy" : "OrderByDescending"; 

    Type[] types = new[] { q.ElementType, exp.Body.Type }; 

    var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp); 

    return q.Provider.CreateQuery<T>(mce); 
} 
+0

參見:http://stackoverflow.com/questions/298725/multiple-order-by-in-linq – RBZ

+0

這會工作,但後來我不能使用參數「sortColumn」來排序需要的任何列,除非我使用很多if(){} s。 – Catalin

+1

首先,你不應該在這裏返回'IOrderedQueryable'嗎?其次,你不能創建另一個擴展'IOrderedQueryable'的副本,而不是使用'ThenBy'和'ThenByDescending'作爲'Queryable'方法的'IQueryable'嗎? – SPFiredrake

回答

6

Handle GridView.OnSorting() and create sorting expression dynamically using LINQ

public static class SortExpressionBuilder<T> 
{ 
    private static IDictionary<SortDirection, ISortExpression> directions = new Dictionary<SortDirection, ISortExpression> 
    { 
     { SortDirection.Ascending, new OrderByAscendingSortExpression() }, 
     { SortDirection.Descending, new OrderByDescendingSortExpression() } 
    }; 

    interface ISortExpression 
    { 
     Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression(); 
    } 

    class OrderByAscendingSortExpression : ISortExpression 
    { 
     public Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression() 
     { 
      return (c, f) => c.OrderBy(f); 
     } 
    } 

    class OrderByDescendingSortExpression : ISortExpression 
    { 
     public Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression() 
     { 
      return (c, f) => c.OrderByDescending(f); 
     } 
    } 

    public static Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> CreateExpression(SortDirection direction) 
    { 
     return directions[direction].GetExpression(); 
    } 
} 

public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> collection, string columnName, SortDirection direction) 
{ 
    ParameterExpression param = Expression.Parameter(typeof(T), "x"); // x 
    Expression property = Expression.Property(param, columnName);  // x.ColumnName 
    Func<T, object> func = Expression.Lambda<Func<T, object>>(  // x => x.ColumnName 
     Expression.Convert(Expression.Property(param, columnName), 
     typeof(object)), param 
    ).Compile(); 

    Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> expression = SortExpressionBuilder<T>.CreateExpression(direction); 
    IEnumerable<T> sorted = expression(collection, func); 
    return sorted; 
} 

並從底部鏈接:

3

你可以嘗試排序上類似下面的表達式的東西:

.OrderBy(x => BirthDate == DateTime.Now.Date ? 0 : 1).ThenBy(sortColumn);