2011-05-20 19 views
7

genişletme ben harika tarafından Marc Gravell dinamik bir sipariş bulduk: Bir sınıfa, LinqHelper koymak ettikMarc Gravell Dinamik Linq OrderBy

Dynamic LINQ OrderBy on IEnumerable<T>

.

var q = db.tblJobHeaders; 

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

sınıfları bu şunlardır modernleşmek için:

/// <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 ben geçen oldukça yeniyim benim kodda bunu böylece bu sınıfta ben de iki yeni sınıflar oluşturduk Linq, işlevlere göre değişir (biraz karıştırır). Herkes yardımcı olabilir, ben düzgün var q geçen ve sonra dönen değilim bu konuyla ilgili biraz kafam karıştı

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

: hata veriyor

OBys.ExecuteOrderBys(q); 

: Şu anda üzerinde hata alıyorum doğru mu?

cevap

4

Bahse girerim q türünün IQueryable<T> ve IOrderedQueryable<T> değil. Sadece imzayı değiştirmek işe yaramalı çünkü OrderBy ile başlıyorsunuz.

O zaman ThenBy s için IOrderedQueryable<T> gerekir. Bunu yalnızca yayınlayabilirsiniz, çünkü önceki aramaya göre IOrderedQueryable<T> ya da OrderBy ya da ThenBy numaralarına sahip olduğunuzdan emin olabilirsiniz. Eğer döküm fikrini beğenmezseniz

, bazı değişiklikler gerekir: kodunuzu nedeniyle IOrderedQueryable<T> için döküme olarak herhangi orderings katmayan eğer olağanüstü başarısız olur

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

Not son. Geri dönüş türünü IQueryable<T> olarak değiştirebilir (daha sonra daha fazla OrderBys ekleyebilme yeteneğini kaybeder) veya yaptığım gibi herhangi bir sipariş yoksa atlayabilirsiniz.

+0

sayesinde bu iş gibi görünüyor ama ExecuteOrderBys' 'in 'ThenBy' ifadeleri hataları atar:' tip argümanları yöntemi için 'LinqHelper.ThenBy (System.Linq.IOrderedQueryable , string)' den çıkarsanamayacağına kullanımı. Açık argüman türlerini belirtmeyi deneyin. ' –

+0

@ Tom: Silly me. Beklenen bir şeydi. Düzenlememe bak. –

+0

Super Bu harika çalışıyor! Her şeyin iyi çalıştığını kontrol edeceğim, yardımlarınız için çok teşekkür ederim! –