Проблема с общей функцией Linq OrderBy - PullRequest
5 голосов
/ 10 сентября 2009

В проводке я увидел следующую функцию, которая позволяет упорядочивать данные, используя обобщенное выражение:

public static IOrderedQueryable<T> OrderBy<T, TKey>(
  this IQueryable<T> source, Expression<Func<T, TKey>> func, bool isDescending) {
  return isDescending ? source.OrderByDescending(func) : source.OrderBy(func);
}

Когда я пытаюсь использовать эту функцию, я получаю сообщение об ошибке: «Тип или имя пространства имен« TKey »не может быть найдено (вы пропустили директиву using или ссылку на сборку?)». Я делаю что-то тупое здесь но я не могу понять это.

Edit:

Пройдя еще немного исследований, я думаю, что моя проблема в том, чтобы построить выражение, которое я передам в него. Можно ли построить выражение, которое может содержать разные типы? Допустим, у моего набора данных есть строка, int и bool, и я хочу использовать описанную выше универсальную функцию для сортировки по любому из элементов. Как мне это сделать?

У меня сейчас работает:

if (IsString)
{
   Expression<Func<T, string>> expString = ...;
   // call orderBy with expString
}
else if (IsInt)
{
   Expression<Func<T, int>> expInt;
   // call orderBy w/ expInt
}
:

Я хочу что-то вроде:

Expression<Func<T, {something generic!}>> exp;
if (IsString)
    exp = ...;
else if (IsInt)
    exp = ...;
:
// call orderBy with exp

Ответы [ 5 ]

4 голосов
/ 14 сентября 2009

Одно быстрое наблюдение: вам не нужно использовать лямбда-выражение (Expression<Func<T,TKey>>). Простой делегат (Func<T,TKey>) в порядке.

Тем не менее, я думаю, что вы, возможно, ищете ответ:

Func<T,IComparable> func = null;
if (IsString)
    func = (T a) => a.SomeStringValue;
else if (IsInt)
    func = (T a) => a.SomeIntValue;
// call orderBy with exp
2 голосов
/ 11 сентября 2009

Моя цель в этом заключается в том, чтобы устранить много повторяющегося кода. В дополнение к обработке восходящего / нисходящего моя функция "OrderBy" обрабатывает некоторые другие общие логики хорошо. Предполагая определение функции в исходной публикации, можно просто сделать это:

if ( {need to sort by integer})
    query = OrderBy(objectT, a => a.myIntegerField, asc);
else if ( {need to sort by string})
    query = OrderBy(objectT, a=> a.myStringField, asc);
:
1 голос
/ 11 сентября 2009

Выражение может иметь только один тип;Мой предпочтительный ответ здесь будет что-то вроде:

IQueryable<T> query = ...
if({case 1}) {
    query = query.OrderBy(x=>x.SomeValue);
} else if({case 2}) {
    query = query.OrderBy(x=>x.SomeOtherValue);
} ...

Однако, если вы хотите сделать что-то более гибкое, вам, вероятно, придется заняться пользовательским Expression написанием;что-то больше похоже .

0 голосов
/ 16 октября 2012

Взгляните на этот ответ

Мой общий обработчик для сортировки:

  • "dgvProcessList" - это мой dataGridView
  • «Процесс» - это мой объект, связанный с ним
  • "e" - это мой DataGridViewCellMouseEventArgs

                PropertyInfo column = (new Process()).GetType().GetProperties().Where(x => x.Name == dgvProcessList.Columns[e.ColumnIndex].Name).First();
            if (isSortedASC == true)
                dgvProcessList.DataSource = ((List<Process>)dgvProcessList.DataSource).OrderByDescending(x => column.GetValue(x, null)).ToList();
            else
                dgvProcessList.DataSource = ((List<Process>)dgvProcessList.DataSource).OrderBy(x => column.GetValue(x, null)).ToList();
    
            isSortedASC = !isSortedASC;
            dgvProcessList.ClearSelection();
    

Приветствия

0 голосов
/ 14 сентября 2009

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

http://blogs.msdn.com/swiss_dpe_team/archive/2008/06/05/composable-linq-to-sql-query-with-dynamic-orderby.aspx

или

http://www.equivalence.co.uk/archives/819

или

http://www.rocksthoughts.com/blog/archive/2008/01/24/linq-to-sql-dynamic-queries.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...