好吧,我發現this,這將讓我做這件事:Sql的Linq - 庫模式 - 動態排序依據
public IList<Item> GetItems(string orderbyColumn)
{
return _repository.GetItems().OrderBy(orderByColumn).ToList();
}
這是做「動態」排序的最佳方式?我希望能夠將字段名稱作爲字符串(以及排序方向)傳遞給我的服務,並讓它以正確的方式排序。
好吧,我發現this,這將讓我做這件事:Sql的Linq - 庫模式 - 動態排序依據
public IList<Item> GetItems(string orderbyColumn)
{
return _repository.GetItems().OrderBy(orderByColumn).ToList();
}
這是做「動態」排序的最佳方式?我希望能夠將字段名稱作爲字符串(以及排序方向)傳遞給我的服務,並讓它以正確的方式排序。
如果你只是不完整的動態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);
}
這當然是一種可行的動態排序方式。 Ch00k在關於「強類型動態Linq排序」的his answer至this question中提供了另一選項。我個人更喜歡Ch00k的方法,因爲它涉及一些編譯時檢查,並且涉及的代碼很少。
他的回答(Ch00k)將被重構安全爲好,做一個財產的重命名,代碼更新,與屬性名稱的字符串,那不會發生! – 2009-09-27 18:22:51
如果你已經決定它必須是一個字符串,那麼你的選擇是有限的。動態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;
它不一定是一個字符串,但是我如何將控制器的排序列傳遞給Repository/Service? – Martin 2009-09-29 00:52:09
如果不是一個字符串,那麼唯一的另一個明智的選擇是一個lambda表達式,或者一個封裝多個lambda表達式的對象。或者只是使用現有的OrderBy/ThenBy。 – 2009-09-29 04:22:06
似乎博客條目是死鏈接。 @ ray2k ...你能更新嗎? – 2011-06-29 12:54:49
完成。 http://blog.invalidoperation.com/2011/07/linq-to-sql-and-objectdatasource-bff.html – ray2k 2011-07-04 19:05:28
看起來新鏈接也是死的。你可以在你的答案裏重新發布解決方案嗎? – jahu 2014-01-30 11:12:51