好的,我找到了this,这将允许我这样做:
public IList<Item> GetItems(string orderbyColumn)
{
return _repository.GetItems().OrderBy(orderByColumn).ToList();
}
这是进行“动态”排序的最佳方式吗?我希望能够将列名作为字符串(和排序方向)传递给我的服务,并让它以正确的方式排序。
答案 0 :(得分:9)
这当然是一种可行的动态排序方式。 Ch00k在his answer至this question中提供了另一个关于“强类型动态Linq排序”的选项。我个人更喜欢Ch00k的方法,因为涉及一些编译时检查,并且涉及的代码非常少。
答案 1 :(得分: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;
答案 2 :(得分:1)
如果您只是在动态排序之后没有完整的Dynamic-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);
}