C# 泛型Linq OrderBy函数的问题

C# 泛型Linq OrderBy函数的问题,c#,linq,lambda,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(fun

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

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);
}
公共静态IOrderedQueryable OrderBy(
此IQueryable源代码、表达式函数、布尔值(isDescending){
return isDescending?source.OrderByDescending(func):source.OrderBy(func);
}
当我尝试使用此函数时,我收到一个错误,提示“找不到类型或命名空间名称“TKey”(是否缺少using指令或程序集引用?)。我在这里做了一些愚蠢的事情,但我无法理解

编辑:

在做了更多的研究之后,我认为我的问题在于构建我传递给它的表达式。是否可以构建一个可以包含不同类型的表达式?假设我的数据集有一个字符串、一个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
}
:
if(IsString)
{
表达式expString=。。。;
//使用expString调用orderBy
}
否则如果(IsInt)
{
表达式导出;
//调用orderBy w/expInt
}
:
我想要像这样的东西:

Expression<Func<T, {something generic!}>> exp;
if (IsString)
    exp = ...;
else if (IsInt)
    exp = ...;
:
// call orderBy with exp
IQueryable<T> query = ...
if({case 1}) {
    query = query.OrderBy(x=>x.SomeValue);
} else if({case 2}) {
    query = query.OrderBy(x=>x.SomeOtherValue);
} ...
表达式exp;
如果(IsString)
exp=。。。;
否则如果(IsInt)
exp=。。。;
:
//使用exp调用orderBy

表达式只能有一种类型;我的首选答案如下:

Expression<Func<T, {something generic!}>> exp;
if (IsString)
    exp = ...;
else if (IsInt)
    exp = ...;
:
// call orderBy with exp
IQueryable<T> query = ...
if({case 1}) {
    query = query.OrderBy(x=>x.SomeValue);
} else if({case 2}) {
    query = query.OrderBy(x=>x.SomeOtherValue);
} ...
IQueryable查询=。。。
if({case 1}){
query=query.OrderBy(x=>x.SomeValue);
}else if({case 2}){
query=query.OrderBy(x=>x.SomeOtherValue);
} ...

但是,如果您想做一些更灵活的事情,您可能需要进入自定义的
表达式
编写;一些东西。

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

一个快速观察:您实际上不需要使用lambda表达式(
表达式
)。一个简单的委托(
Func
)就可以了

也就是说,我认为你可能要寻找的答案是:

Func<T,IComparable> func = null;
if (IsString)
    func = (T a) => a.SomeStringValue;
else if (IsInt)
    func = (T a) => a.SomeIntValue;
// call orderBy with exp
Func Func=null;
如果(IsString)
func=(ta)=>a.SomeStringValue;
否则如果(IsInt)
func=(ta)=>a.SomeIntValue;
//使用exp调用orderBy

我认为您需要的是在linq中拥有动态orderby子句的能力。有关此主题的一些好文章,请参阅

看一看

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

  • “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();
    
    PropertyInfo column=(new Process()).GetType().GetProperties().Where(x=>x.Name==dgvProcessList.Columns[e.ColumnIndex].Name).First();
    如果(isSortedASC==true)
    dgvProcessList.DataSource=((列表)dgvProcessList.DataSource).OrderByDescending(x=>column.GetValue(x,null)).ToList();
    其他的
    dgvProcessList.DataSource=((List)dgvProcessList.DataSource).OrderBy(x=>column.GetValue(x,null)).ToList();
    isSortedASC=!isSortedASC;
    dgvProcessList.ClearSelection();
    

干杯

这似乎很好。你是如何使用这种方法的?你把它添加到一个静态类中了吗?这是我最初拥有的,但由于我有很多字段,需要处理升序/降序排序,所以我最终得到了大量的“重复”代码。我发布的答案似乎很有效。这似乎是我一直在寻找的。但是,我对它进行了一些处理,无法将其编译。当我试图将func传递给OrderBy函数时,编译器会抱怨。如果你的方法可行的话,它会稍微干净一点,但不幸的是,我现在不能花更多的时间在它上面。当你有时间的时候,请告诉我你看到的编译器错误是什么。我终于回到这个问题上了。我认为问题在于,在我的自定义orderBy函数中,我调用了ThenBy,它不接受Func参数-它需要lambda表达式。您可以创建一个接受Func的
ThenBy
重载。只有在需要以某种方式分析lambda表达式时,才应使用它们。如果只需要执行表达式,那么应该使用委托。