Linq to Sql - 存储库模式 - 动态OrderBy

时间:2009-09-24 02:43:06

标签: linq linq-to-sql

好的,我找到了this,这将允许我这样做:

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

这是进行“动态”排序的最佳方式吗?我希望能够将列名作为字符串(和排序方向)传递给我的服务,并让它以正确的方式排序。

3 个答案:

答案 0 :(得分:9)

这当然是一种可行的动态排序方式。 Ch00khis answerthis 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);
    }