我在帖子中看到了以下功能,允许用户使用通用表达式订购数据:
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
答案 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)
我认为您可能正在寻找的是在linq中拥有动态orderby子句的能力。有关该主题的一些好文章,请参阅
或
http://www.equivalence.co.uk/archives/819
或
http://www.rocksthoughts.com/blog/archive/2008/01/24/linq-to-sql-dynamic-queries.aspx
答案 4 :(得分:0)
我的排序通用处理程序是:
“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();
干杯