2009-09-24 41 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