2016-06-24 2 views
1

Я создаю репозиторий и хотел бы иметь возможность передавать список видов функции, чтобы получить сущности обратно в правильном порядке и, возможно, выгружать страницы.Использовать список сортировки для сортировки запроса

я узнал, что будет правильно LINQ родов, если вы используете обратный список видов и использовать OrderBy для каждого выражения сортировки ..

 foreach (var s in sorts.Reverse()) 
     { 
      query = query.OrderBy(s); 
     } 

Однако при тестировании добавления направления сортировки я обнаружил, что только принимает первое направление сортировки и, похоже, применяет это направление к каждому виду.

private void applySorts(ref IQueryable<TEntity> query, Dictionary<Expression<Func<TEntity, dynamic>>, string> sorts) 
    { 
     if (sorts != null) 
     { 
      foreach (var s in sorts.Reverse()) 
      { 
       Expression<Func<TEntity, dynamic>> expr = s.Key; 
       string dir = s.Value; 
       if (dir == "d") 
       { 
        query = query.OrderByDescending(expr); 
       } 
       else 
       { 
        query = query.OrderBy(expr); 
       } 
      } 
     } 
    } 

Первоначально я пытался использовать OrderBy на первом роде, а затем перейти к ThenBy, но это не представляется возможным, потому что ThenBy требует типа IOrderedQueryable.

Я хотел бы отметить, что использование словаря может быть не лучшим, если у вас есть идеи, пожалуйста, поделитесь. Тем не менее, я просто хотел запустить его и посмотреть, как все идет.

Я использую C#, Linq и Entity Framework.

Заранее благодарим за ваше время.

Обновление: К сожалению, я обнаружил, что это не поддерживает сортировку чисел. Error (Невозможно бросить тип «System.Int32» к типу 'System.Object.)

+0

Я бы использовал SortedDictionary с ключом, являющимся пользовательским классом, который наследует IComparable, который реализует метод CompareTo(). См. Публикацию: http://stackoverflow.com/questions/4188013/c-sharp-interfaces-how-to-implement-icomparable – jdweng

ответ

0

Вы можете использовать ThenBy() метод цепочки фильтры, как это:

bool first = true; 

foreach(var s in sorts) 
{ 
    query = first ? query.OrderBy(s) : query.ThenBy(s); 
} 
// It will became like query.OrderBy(a => a.A).ThenBy(a => a.B).ThenBy(a => a.C)... 

Вы также можете использовать сортировку по несколько столбцов в запросе LINQ, если вы знаете свойство, на которых вы будете сортировать:

var result = (from row in list 
       orderby row.A, row.B, row.C 
       select row).ToList(); 
+0

'var query = query.OrderBy (sorts [0]);' не будет компилироваться. – hvd

+0

@hvd Хорошо, я не заметил, что это словарь. :) Тогда он может просто изменить цикл на 'foreach' вместо' for' так, как он. Просто примените 'OrderBy()' к первому выражению сортировки и 'ThenBy()' ко всем остальным. –

+0

Хех, на самом деле я имел в виду, что у вас не может быть локальной переменной с тем же именем, что и параметр, но да, это тоже. :) С вашей отредактированной версией 'query.ThenBy' не будет компилироваться,' query' имеет тип 'IQueryable '. Вы были ближе к своей первой версии, вам нужна отдельная переменная, вам просто нужно дать ей другое имя. – hvd

1

грамматически, все, что вам нужно, это температура переменного типа IOrderedQueryable.

Я хотел бы попробовать что-то вроде:

private void applySorts(ref IQueryable<TEntity> query, Dictionary<Expression<Func<TEntity, dynamic>>, string> sorts) 
{ 
    if (sorts != null) 
    { 
     IOrderedQueryable<TEntity> tempQuery = null; 
     bool isFirst = true; 
     foreach (var s in sorts.Reverse()) 
     { 
      Expression<Func<TEntity, dynamic>> expr = s.Key; 
      string dir = s.Value; 
      if (first) 
      { 
       first = false; 
       if (dir == "d") 
       { 
        tempQuery = query.OrderByDescending(expr); 
       } 
       else 
       { 
        tempQuery = query.OrderBy(expr); 
       } 
      } 
      else 
      { 
       if (dir == "d") 
       { 
        tempQuery = tempQuery.ThenByDescending(expr); 
       } 
       else 
       { 
        tempQuery = tempQuery.ThenBy(expr); 
       } 
      } 
     } 
     query = tempQuery; 
    } 
} 

Edit:

Ключ к вышеуказанному раствору является то, что IOrderedQueryable является IQueryable.

Я не пробовал это сам. Однако я хотел бы подчеркнуть, что это только грамматическое решение.

Смежные вопросы