2009-09-24 38 views
2

好吧,我發現this,這將讓我做這件事:Sql的Linq - 庫模式 - 動態排序依據

public IList<Item> GetItems(string orderbyColumn) 
{ 
    return _repository.GetItems().OrderBy(orderByColumn).ToList(); 
} 

這是做「動態」排序的最佳方式?我希望能夠將字段名稱作爲字符串(以及排序方向)傳遞給我的服務,並讓它以正確的方式排序。

回答

1

如果你只是不完整的動態Linq的東西動態排序後,你可以檢查出後我寫了這一段時間回來:click

編輯:我不知道真正的博客了,所以這裏的實際擴展方法:

public static IQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class 
    { 
     if (string.IsNullOrEmpty(sortExpression)) 
      return source; // nothing to sort on 

     var entityType = typeof(TEntity); 
     string ascSortMethodName = "OrderBy"; 
     string descSortMethodName = "OrderByDescending";    
     string[] sortExpressionParts = sortExpression.Split(' '); 
     string sortProperty = sortExpressionParts[0]; 
     string sortMethod = ascSortMethodName; 

     if (sortExpressionParts.Length > 1 && sortExpressionParts[1] == "DESC") 
      sortMethod = descSortMethodName;  

     var property = entityType.GetProperty(sortProperty); 
     var parameter = Expression.Parameter(entityType, "p"); 
     var propertyAccess = Expression.MakeMemberAccess(parameter, property); 
     var orderByExp = Expression.Lambda(propertyAccess, parameter); 

     MethodCallExpression resultExp = Expression.Call(
              typeof(Queryable), 
              sortMethod, 
              new Type[] { entityType, property.PropertyType }, 
              source.Expression, 
              Expression.Quote(orderByExp)); 

     return source.Provider.CreateQuery<TEntity>(resultExp); 
    } 
+0

似乎博客條目是死鏈接。 @ ray2k ...你能更新嗎? – 2011-06-29 12:54:49

+0

完成。 http://blog.invalidoperation.com/2011/07/linq-to-sql-and-objectdatasource-bff.html – ray2k 2011-07-04 19:05:28

+0

看起來新鏈接也是死的。你可以在你的答案裏重新發布解決方案嗎? – jahu 2014-01-30 11:12:51

9

這當然是一種可行的動態排序方式。 Ch00k在關於「強類型動態Linq排序」的his answerthis question中提供了另一選項。我個人更喜歡Ch00k的方法,因爲它涉及一些編譯時檢查,並且涉及的代碼很少。

+0

他的回答(Ch00k)將被重構安全爲好,做一個財產的重命名,代碼更新,與屬性名稱的字符串,那不會發生! – 2009-09-27 18:22:51

4

如果你已經決定它必須是一個字符串,那麼你的選擇是有限的。動態LINQ庫確實可以完成這項工作,或者如果你不知道它是如何工作的,可以看看這個previous answer,它在運行時從字符串中生成Expression

目前代碼只接受單個成員,並具有單獨的升序/降序方法,但從這個例子來說,傳遞更復雜的字符串並拆分它應該相當簡單;基本上爲:

IQueryable<T> query = ... 
string[] portions = orderBy.Split(' '); // split on space, arbitrarily 
if(portions.Length == 0) throw new ArgumentException(); 
IOrderedQueryable<T> orderedQuery = query.OrderBy(portions[0]); 
for(int i = 1 ; i < portions.Length ; i++) { // note we already did the zeroth 
    orderedQuery = orderedQuery.ThenBy(portions[i]); 
} 
return orderedQuery; 
+0

它不一定是一個字符串,但是我如何將控制器的排序列傳遞給Repository/Service? – Martin 2009-09-29 00:52:09

+0

如果不是一個字符串,那麼唯一的另一個明智的選擇是一個lambda表達式,或者一個封裝多個lambda表達式的對象。或者只是使用現有的OrderBy/ThenBy。 – 2009-09-29 04:22:06