Generic Linq OrderBy函数的问题
我在post中看到了以下函数,它允许用户使用generics表达式对数据进行排序:
public static IOrderedQueryable OrderBy( this IQueryable source, Expression<Func> func, bool isDescending) { return isDescending ? source.OrderByDescending(func) : source.OrderBy(func); }
当我尝试使用这个函数时,我得到一个错误,说“找不到类型或命名空间名称”TKey’(你错过了使用指令或程序集引用吗?)“。我在这里做了一些蠢事,但我可以弄清楚。
编辑:
在做了一些研究之后,我认为我的问题在于构建我传递给它的Expression。 是否可以构建一个可以包含不同类型的表达式? 假设我的数据集有一个字符串,一个int和一个bool,我想使用上面的generics函数来排序任何项目。 我该怎么做呢?
我现在有这个工作:
if (IsString) { Expression<Func> expString = ...; // call orderBy with expString } else if (IsInt) { Expression<Func> expInt; // call orderBy w/ expInt } :
我想要的东西:
Expression<Func> exp; if (IsString) exp = ...; else if (IsInt) exp = ...; : // call orderBy with exp
一个快速观察:你真的不需要使用lambda表达式( Expression
)。 一个简单的委托( Func
)很好。
也就是说,我认为您可能正在寻找的答案是:
Func func = null; if (IsString) func = (T a) => a.SomeStringValue; else if (IsInt) func = (T a) => a.SomeIntValue; // call orderBy with exp
我的目标是消除大量重复的代码。 除了处理升序/降序我的“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); :
表达式只能有一种类型; 我在这里的首选答案是:
IQueryable query = ... if({case 1}) { query = query.OrderBy(x=>x.SomeValue); } else if({case 2}) { query = query.OrderBy(x=>x.SomeOtherValue); } ...
但是,如果你想做一些更灵活的事情,你可能需要进入自定义Expression
写作; 更像这样的东西。
我认为你可能正在寻找的是在linq中拥有动态orderby子句的能力。 关于这个话题的一些好文章见
要么
http://www.equivalence.co.uk/archives/819
要么
http://www.rocksthoughts.com/blog/archive/2008/01/24/linq-to-sql-dynamic-queries.aspx
看看这个答案
我的排序通用处理程序是:
- “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
)dgvProcessList.DataSource).OrderByDescending(x => column.GetValue(x, null)).ToList(); else dgvProcessList.DataSource = ((List )dgvProcessList.DataSource).OrderBy(x => column.GetValue(x, null)).ToList(); isSortedASC = !isSortedASC; dgvProcessList.ClearSelection();
干杯