2012-10-22 56 views
4

可能重複:
Dynamic LINQ OrderBy有沒有可能用反射做到這一點?

我的(如果你想知道KendoUI網格)傳遞給服務器從客戶端電網控制自定義排序選項列表。這些排序選項的屬性可以按字符串排序。我編寫了一個switch方法,它將檢查排序對象的值並應用適當的LINQ。

private IQueryable<Report> SortReports(IQueryable<Report> reports, KendoSort sort) 
    { 
     switch (sort.Field) 
     { 
      case "name": 
       return sort.Dir == "asc" ? reports.OrderBy(x => x.Name) : reports.OrderByDescending(x => x.Name); 
      case "description": 
       return sort.Dir == "asc" ? reports.OrderBy(x => x.Description) : reports.OrderByDescending(x => x.Description); 
      default: 
       return sort.Dir == "asc" ? reports.OrderBy(x => x.Id) : reports.OrderByDescending(x => x.Id); 
     } 
    } 

這工作正常,但似乎很難看。我怎麼可以用反射來做到這一點,以便我不必爲每種類型的實體編寫自定義函數?如果我可以只用一個單獨的函數來完成這個任務,那將是非常好的。

+0

我沒有看到這裏會做什麼反射,但是你可以用一個枚舉來代替你的字符串。 – LightStriker

+0

[動態LINQ OrderBy](http://stackoverflow.com/questions/41244/dynamic-linq-orderby) –

回答

2

你可以使用動態LINQ。這是Scott Gu的關於它的blog post

+0

好的解決方案。我不確定我更喜歡哪一個! – Chev

+0

你讓我的生活變得如此簡單。在存儲庫方法中執行此操作:'foreach(var sort in kendoSorts) reports = reports.OrderBy(string.Format(「{0} {1}」,sort.Field,sort.Dir));'foreach允許它處理多種分揀。 – Chev

1

Marc Gravell有一個叫做FastMember的很棒的小圖書館。您可以使用它像這樣:

private IQueryable<Report> SortReports(IQueryable<Report> reports,KendoSort sort) 
{ 
    var accessor = TypeAccessor.Create(typeof(Report)); 
    return sort.Dir == "asc" ? 
     reports.OrderBy(x => accessor[x,sort.Field]) : 
     reports.OrderByDescending(x => accessor[x,sort.Field])); 
} 
+0

不錯!如果我使方法通用,我可以換出Report,並將其用於任何我想要的集合。完善。 – Chev

+0

是的,這應該很好地工作。 –

1

使用反射,其中KendoSort.Property是返回所需的排序值報告財產的PropertyInfo。

private IQueryable<Report> SortReports(IQueryable<Report> reports, KendoSort sort) 
{ 
    return sort.Dir == "asc" ? reports.OrderBy(x => sort.Property.GetValue(x)) : reports.OrderByDescending(x => sort.Property.GetValue(x)); 
} 

但是後來反射比較慢。其他解決方案可能會更好。

+0

+1用於回答我的確切問題,即使反射實際上並不是我想要的:) – Chev

1

以下應該創建你想要的動態排序功能。

ParameterExpression pe = Expression.Parameter(typeof(Report), "x"); 
LambdaExpression le = Expression.Lambda(
    Expression.PropertyOrField(pe, sort.Field), 
    new List<ParameterExpression>() {pe}); 

var leCompiled = (Func<Report, string>)le.Compile();     

return sort.Dir == "asc" ? reports.OrderBy(leCompiled) : reports.OrderByDescending(leCompiled); 

它以x => x.ReportProperty的形式創建一個Func委託,其中ReportProperty是sort.Field的值。

相關問題