2011-05-20 95 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