2017-01-25 10 views
0

Нужно сортировать/заказывать список данных на основе неопределенного количества столбцов (1 или более).Сортировка/заказ Неопределенное количество столбцов (LINQ Entity Framework)

Что я пытаюсь сделать, это перебрать нужных столбцов и добавить OrderBy или ThenBy в зависимости от их числа в списке query'd, но я неудачно ...

Done, но он не компилируется:

var query = GetAllItems(); //returns a IQueriable list of items 

//for each selected column 
for (int i = 0; i < param.Columns.Length; i++) 
{ 
    if (i == 0) 
    { 
     query = query.OrderBy(x => x.GetType().GetProperty(param.Columns[i].Name)); 
    } 
    else 
    { 
     //ERROR: IQueriable does not contain a definition for "ThenBy" and no extension method "ThenBy"... 
     query = query.ThenBy(x => x.GetType().GetProperty(param.Columns[i].Data)); 
    } 
} 

Как решить эту проблему? Или любая альтернатива для выполнения этого требования?

РЕШЕНИЕ: @ Решение Дэйва-Киддера хорошо известно и устраняет ошибки компиляции, которые у меня были. Только одна проблема, OrderBy только выполняет (фактически сортирует результаты) после листинга ToList(). Это проблема, потому что я не могу преобразовать ToList обратно в IOrderedQueryable. Итак, после некоторых исследований я столкнулся с решением, которое разрешает все мои проблемы.

Microsoft сборки для .Net 4.0 функциональности динамического языка: https://github.com/kahanu/System.Linq.Dynamic

using System.Linq.Dynamic; //need to install this package 

Обновленный код:

var query = GetAllItems(); //returns a IQueriable list of items 

List<string> orderByColumnList = new List<string>(); //list of columns to sort 

for (int i = 0; i < param.Columns.Length; i++) 
{ 
    string column = param.Columns[i].Name; 
    string direction = param.Columns[i].Dir; 

    //ex.: "columnA ASC" 
    string orderByColumn = column + " " + direction; 

    //add column to list 
    orderByColumnList.Add(orderBy); 
} 

//convert list to comma delimited string 
string orderBy = String.Join(",", orderByColumnList.ToArray()); 

//sort by all columns, yay! :-D 
query.OrderBy(orderBy).ToList(); 

ответ

0

вы должны написать ThenBy после OrderBy как это:

query = query 
      .OrderBy(t=> // your condition) 
      .ThenBy(t=> // next condition); 
+0

Я знаю, моя основная проблема заключается в том, чтобы динамически выполнять неопределенное количество столбцов. – Ricky

2

проблема в том, что ThenBy не определен в IQueryable, но на IOrderedQuerya (который является результатом IQueryable.OrderBy). Таким образом, вам нужно определить новую переменную для IOrderedQueryable, чтобы выполнять последующие вызовы ThenBy. Я немного изменил исходный код, чтобы использовать System.Data.DataTable (чтобы получить аналогичную структуру для вашего объекта param). Код также предполагает, что в DataTable имеется по крайней мере один столбец.

// using System.Data.DataTable to provide similar object structure as OP 
DataTable param = new DataTable(); 
IQueryable<DataTable> query = new List<DataTable>().AsQueryable(); 

// OrderBy returns IOrderedQueryable<TSource>, which is the interface that defines 
// "ThenBy" so we need to assign it to a different variable if we wish to make subsequent 
// calls to ThenBy 
var orderedQuery = query.OrderBy(x => x.GetType().GetProperty(param.Columns[0].ColumnName)); 

//for each other selected column 
for (int i = 1; i < param.Columns.Count; i++) 
{ 
    orderedQuery = orderedQuery.ThenBy(x => x.GetType().GetProperty(param.Columns[i].ColumnName)); 
} 
+0

спасибо @Dave, он выполняет эту работу. Есть лишь небольшая деталь, которая мешает работе. Чтобы заказ выполнялся и фактически выполнялся, запрос должен использовать .ToList(). Но при использовании ToList() все это снова разваливается ... – Ricky