【问题标题】:Linq to Sql - Repository Pattern - Dynamic OrderByLinq to Sql - 存储库模式 - 动态 OrderBy
【发布时间】:2009-09-24 02:43:06
【问题描述】:

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

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

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

【问题讨论】:

    标签: linq linq-to-sql


    【解决方案1】:

    这当然是一种可行的动态排序方式。 Ch00khis answerthis question 中提供了另一个关于“强类型动态 Linq 排序”的选项。我个人更喜欢 Ch00k 的方法,因为它涉及到一些编译时检查,而且涉及的额外代码非常少。

    【讨论】:

    • 他的答案 (Ch00k) 也将是重构安全的,重命名属性,代码更新,属性名称在字符串中,这不会发生!跨度>
    【解决方案2】:

    如果您已经决定它必须是一个字符串,那么您的选择就会受到一定的限制。动态 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;
    

    【讨论】:

    • 它不一定是字符串,但是我如何将排序列从控制器传递到存储库/服务?
    • 如果不是字符串,那么唯一明智的选择是 lambda 表达式,或者封装多个 lambda 表达式的对象。或者只使用现有的 OrderBy/ThenBy。
    【解决方案3】:

    如果您只是在没有完整 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);
        }
    

    【讨论】:

    • 似乎博客条目是死链接。 @ray2k...你能更新一下吗?
    • 看起来新链接也失效了。您能否在答案中重新发布解决方案?
    猜你喜欢
    • 1970-01-01
    • 2011-04-29
    • 2011-01-02
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    • 2010-09-23
    相关资源
    最近更新 更多