Generic Linq OrderBy函数的问题

时间:2009-09-10 19:30:36

标签: c# linq lambda

我在帖子中看到了以下功能,允许用户使用通用表达式订购数据:

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'(你是否错过了使用指令或程序集引用?)“。我在这里做一些蠢事但我无法弄清楚。

编辑:

在做了一些研究之后,我认为我的问题在于构建我传递给它的Expression。是否可以构建一个可以包含不同类型的表达式?假设我的数据集有一个字符串,一个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 个答案:

答案 0 :(得分:4)

一个快速观察:你真的不需要使用lambda表达式(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

答案 1 :(得分:2)

我的目标是消除大量重复的代码。除了处理升序/降序我的“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);
:

答案 2 :(得分:1)

表达式只能有一种类型;我在这里的首选答案是:

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

但是,如果你想做一些更灵活的事情,你可能需要进入自定义Expression写作; more like this

答案 3 :(得分:0)

答案 4 :(得分:0)

查看this answer

我的排序通用处理程序是:

  • “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();
    

干杯