通用 Linq OrderBy 函数的问题

发布于 2024-08-04 14:14:40 字数 975 浏览 3 评论 0 原文

我在一篇帖子中看到以下函数,它允许人们使用通用表达式来排序数据:

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”(您是否缺少使用指令或程序集引用?)”。我在这里做了一些愚蠢的事情,但我无法弄清楚。

编辑:

在做了更多研究之后,我认为我的问题是构建我传递给它的表达式。是是否可以构建一个可以包含不同类型的表达式?假设我的数据集有一个字符串、一个整数和一个布尔值,并且我想使用上面的通用函数来按任何项目进行排序,我该怎么做

?现在就可以工作了:

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

I saw the following function in a posting which allows one to order data using a generic expression:

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);
}

When I try to use this function I get an error saying "The type or namespace name "TKey' could not be found (are you missing a using directive or an assembly reference?)". I'm doing something dumb here but I can't figure it out.

Edit:

After doing a bit more research, I think my problem is in building the Expression that I pass into it. Is it possible to build an expression that can contain different types? Let's say my dataset has a string, an int, and a bool and I want to use the generic function above to sort by any of the items. How do I do this?

I have this working now:

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

I want something like:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

烙印 2024-08-11 14:14:40

一个快速观察:您实际上并不需要使用 lambda 表达式 (Expression>)。一个简单的委托 (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

One quick observation: You don't really need to use a lambda expression (Expression<Func<T,TKey>>). A simple delegate (Func<T,TKey>) is fine.

That said, I think the answer you might be looking for is this:

Func<T,IComparable> func = null;
if (IsString)
    func = (T a) => a.SomeStringValue;
else if (IsInt)
    func = (T a) => a.SomeIntValue;
// call orderBy with exp
离鸿 2024-08-11 14:14:40

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

My goal in this was to eliminate a lot of repetitious code. In addition to handling the ascending/descending my "OrderBy" function handles some other common logic has well. Assuming the function definition in the original posting, one can simply do this:

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);
:
剩一世无双 2024-08-11 14:14:40

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

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

但是,如果您想做一些更灵活的事情,您可能需要进行自定义Expression编写; 更像这样

The expression can only have one type; my preferred answer here would be something like:

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

However, if you want to do something more flexible, you'd probably need to get into custom Expression writing; something more like this.

离笑几人歌 2024-08-11 14:14:40

看看 这个答案

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

  • “dgvProcessList”是我的 dataGridView
  • “Process”是我绑定的对象到它
  • “e”是我的DataGridViewCellMouseEventArgs

     PropertyInfo 列 = (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();
            别的
                dgvProcessList.DataSource = ((List)dgvProcessList.DataSource).OrderBy(x =>column.GetValue(x, null)).ToList();
    
            isSortedASC = !isSortedASC;
            dgvProcessList.ClearSelection();
    

干杯

Take a look at this answer

My generic handler for sorting is:

  • "dgvProcessList" is my dataGridView
  • "Process" is my object binded to it
  • "e" is my 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();
    

Cheers

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文