2011-05-20 63 views
7

我發現馬克Gravell的動態訂單由大:擴展馬克Gravell的動態LINQ的排序依據

Dynamic LINQ OrderBy on IEnumerable<T>

我已經把它在一個類中,LinqHelper。在這一類我還創建了兩個新的類,所以,在我的代碼,我可以這樣做:

var q = db.tblJobHeaders; 

LinqHelper.OrderByCollection OBys = new LinqHelper.OrderByCollection(); 
OBys.AddOrderBy("some field", true); 
OBys.AddOrderBy("anotherfield", false); 
OBys.ExecuteOrderBys(q); 

的類來達致這是:

/// <summary> 
/// A collection of order bys 
/// </summary> 
public class OrderByCollection 
{ 
    private ArrayList Orderings = new ArrayList(); 

    public OrderByCollection(){ } 

    /// <summary> 
    /// Add an order by to this collection 
    /// </summary> 
    public void AddOrderBy(string Field, bool Descending) 
    { 
     OrderByObj NewObj = new OrderByObj(Descending, Field); 
     this.Orderings.Add(NewObj); 
    } 

    /// <summary> 
    /// Executes the order bys 
    /// </summary> 
    public IOrderedQueryable<T> ExecuteOrderBys<T>(this IOrderedQueryable<T> source) 
    { 
     int ExecutionIndex = 0; 
     foreach (OrderByObj O in this.Orderings) 
     { 
      if (ExecutionIndex == 0) 
      { 
       if (O.Descending) 
        source = LinqHelper.OrderByDescending(source, O.Field); 
       else 
        source = LinqHelper.OrderBy(source, O.Field); 
      } 
      else 
      { 
       if (O.Descending) 
        source = LinqHelper.ThenByDescending(source, O.Field); 
       else 
        source = LinqHelper.ThenBy(source, O.Field); 
      } 
      ExecutionIndex++; 
     } 
     return (IOrderedQueryable<T>)source; 
    } 
} 

/// <summary> 
/// An order by object 
/// </summary> 
private class OrderByObj 
{ 
    public bool Descending { get; set; } 
    public string Field { get; set; } 

    public OrderByObj(bool IsDescending, string DatabaseField) 
    { 
     this.Descending = IsDescending; 
     this.Field = DatabaseField; 
    } 
} 

Howver我是很新,傳球Linq改變了功能(讓我感到困惑)。我目前得到的錯誤:這給錯誤

OBys.ExecuteOrderBys(q); 

The type arguments for method 'LinqHelper.OrderByCollection.ExecuteOrderBys(System.Linq.IOrderedQueryable)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

我有點困惑這一點,如果有人可以幫助,我是路過的var q正確,然後返回它正確嗎?

回答

4

我敢打賭,q的類型是IQueryable<T>而不是IOrderedQueryable<T>。只需更改簽名即可使用,因爲您從OrderBy開始。

然後您將需要IOrderedQueryable<T>ThenBy s。你可以投它,因爲你確定知道你有一個IOrderedQueryable<T>從以前的調用OrderByThenBy

如果你不喜歡的演員的想法,你需要一些變化:

public IOrderedQueryable<T> ExecuteOrderBys<T>(this IQueryable<T> source) 
{ 
    if(!this.Orderings.Any()) 
     throw new InvalidOperationException("You need to add orderings"); 
    IOrderedQueryable<T> ordered; 
    if (this.Orderings[0].Descending) 
     ordered = LinqHelper.OrderByDescending(source, this.Orderings[0].Field); 
    else 
     ordered = LinqHelper.OrderBy(source, this.Orderings[0].Field); 
    foreach(var ordering in this.Orderings.Skip(1)) 
    { 
     if (ordering.Descending) 
      ordered = LinqHelper.ThenByDescending(source, ordering.Field); 
     else 
      ordered = LinqHelper.ThenBy(source, ordering.Field); 
    } 
    return ordered; 
} 

注意你的代碼將失敗壯觀,如果你不加,因爲中投IOrderedQueryable<T>的任何排序,結束。您可以將返回類型更改爲IQueryable<T>(後者失去「附加」更多OrderBys的能力),或者在沒有排序時拋出,就像我一樣。

+0

謝謝,這似乎工作,但在'ExecuteOrderBys'上的「ThenBy」語句中引發錯誤:'對方法的類型參數「LinqHelper.ThenBy (System.Linq.IOrderedQueryable ,字符串)」不能從推斷用法。嘗試明確指定類型參數。「# – 2011-05-20 10:28:12

+0

@Tom:傻我。這是可以預料的。看我的編輯。 – 2011-05-20 10:30:42

+0

超級這似乎很好!我只是檢查一切正常,謝謝你的幫助! – 2011-05-20 10:35:37