2011-05-20 9 views
7

encontré orden dinámico de Marc Gravell por grandes:La extensión de Marc Gravell dinámico LINQ OrdenarPor

Dynamic LINQ OrderBy on IEnumerable<T>

lo he puesto en una clase, LinqHelper. En esta clase también he creado dos nuevas clases, de modo que en mi código que pueda hacer esto:

var q = db.tblJobHeaders; 

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

Las clases para lograr esto son:

/// <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 yo soy bastante nuevo en paso Linq pasa a funciones (lo confundo un poco). Actualmente me sale el error en:

OBys.ExecuteOrderBys(q); 

que da el error:

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

estoy un poco confundido acerca de esto si alguien puede ayudar, estoy pasando el var q en forma adecuada, y luego regresar es correcto?

Respuesta

4

Apuesto a que el tipo de q es IQueryable<T> y no IOrderedQueryable<T>. Solo cambiar la firma debería funcionar, porque comienzas con OrderBy.

Entonces necesitarás un IOrderedQueryable<T> para el ThenBy s. Puedes simplemente lanzarlo, porque sabes con certeza que tienes un IOrderedQueryable<T> de la llamada anterior a OrderBy o ThenBy.

Si no te gusta la idea del reparto, necesita algunos cambios:

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

anotar el código fallará espectacularmente si no se agrega ningún ordenamientos, debido al reparto de IOrderedQueryable<T> en el fin. Puede cambiar el tipo de devolución a IQueryable<T> (que pierde la capacidad de "adjuntar" más OrderBys más tarde), o lanzar si no hay pedidos, como lo hice.

+0

Gracias, esto parece funcionar, pero genera errores en las declaraciones del 'ThenBy' en 'ExecuteOrderBys':' Los argumentos de tipo para el método 'LinqHelper.ThenBy (System.Linq.IOrderedQueryable , cadena)' no puede deducirse de la uso. Intente especificar explícitamente los argumentos de tipo. –

+0

@Tom: Silly me. Eso era de esperarse. Ver mi edición –

+0

Super esto parece funcionar muy bien! Solo comprobaré que todo funciona bien ¡muchas gracias por tu ayuda! –

Cuestiones relacionadas