循环为多个列设置OrderBy / ThenBy

时间:2018-07-20 19:18:18

标签: c# lambda

我正在将DataTables.Mvc库用于jQuery DataTables。

方法之一是GetSortedColumns(),它返回一个数组,其中包含要排序的每一列的配置。

此对象感兴趣的是NameSortDirection属性。 Name也是数据库表字段名称。 SortDirectionascdesc

起初ThenByThenByDescending是未定义的符号,因此我将ordered创建为IOrderedQueryable。这样可以解析符号,但是看不到这些符号有任何影响。

表示OrderBy,OrderByDescending,ThenBy和ThenByDescending均对filteredRecords中的记录顺序没有影响。

在控制器中:

[AcceptVerbs(HttpVerbs.Post)]
public JsonResult GetUserSelections([ModelBinder(typeof(DataTablesBinder))] IDataTablesRequest requestModel)
{
    // Column Sort
    var filteredRecords = db.AspNetSelectorInputs.Select(si => si);
    var sortedColumns = requestModel.Columns.GetSortedColumns();
    var count = 0;

    foreach (var column in sortedColumns)
    {
        var ordered = filteredRecords as IOrderedQueryable<AspNetSelectorInput>;

        filteredRecords =
            column.SortDirection == DataTables.Mvc.Column.OrderDirection.Ascendant
            ? count == 0
                ? ordered.OrderBy(c => column.Name)
                : ordered.ThenBy(c => column.Name)
            : count == 0
                ? ordered.OrderByDescending(c => column.Name)
                : ordered.ThenByDescending(c => column.Name);

        count++;
    }

    filteredRecords = filteredRecords.Select(si => si).Skip(requestModel.Start).Take(requestModel.Length);

....

谁能看到为什么这不影响filteredRecords的顺序?

有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

它正在根据您的要求进行排序。但是lambda表达式并没有按照您的想法进行。例如,您正在做.OrderBy(c => column.Name),它使用列的名称的文字值进行排序,该文字值对于集合中的每个项目都具有相同的值(请注意{排序}不受c的影响,因此出现不会对您的收藏进行排序。例如,您不妨做.OrderBy(c => "Hello")

您需要执行类似.OrderBy(c => c.YourChoiceOfPropertyName)的操作。除非您不能这样做,否则是因为(大概)属性的名称是column.Name中的字符串值。因此,您需要使用lambda内的反射,以c作为实例来获取该属性的值。这将需要修复所有lambda。例如,在循环内:

var propertyInfo=typeof(AspNetSelectorInput)
    .GetProperty(column.Name);

以及替换lambda表达式:

c=>propertyInfo.GetValue(c)

P.S。除非我缺少某些内容,否则.Select(si => si)的两个实例似乎是多余的。