按任意排序表达式排序列表?

时间:2011-03-02 08:05:14

标签: c# .net vb.net linq

问题:

我有一个通用列表,如下所示:

System.Collections.Generic.List<Question> myquestions = new System.Collections.Generic.List<Question>();

我有一个分页示例,使用从数据库中获取的LINQ表,执行此操作进行分页:

var questions = context.Questions
    .OrderBy(sidx + " " + sord)
    .Skip(pageIndex * pageSize)
    .Take(pageSize);

现在,为了对我填充的代码列表进行分页,我有:

var questionss = myquestions
    .OrderBy(x => x.Id)
    .Skip(pageIndex * pageSize)
    .Take(pageSize);

我想要的是能够通过字符串命令“myquestions”,如上例所示。 这可能吗?

5 个答案:

答案 0 :(得分:3)

由于延迟执行,您可以在单独的语句中链接扩展方法,这意味着您可以根据条件添加不同的排序:

IOrderedQueryable<Question> sorted;
switch (sort) {
  case "Id":  sorted = myquestions.OrderBy(x => x.Id);
  case "Name": sorted = myquestions.OrderBy(x => x.Name);
  case "Size": sorted = myquestions.OrderBy(x => x.Size);
  case "Id Desc":  sorted = myquestions.OrderByDescending(x => x.Id);
  case "Name Desc": sorted = myquestions.OrderByDescending(x => x.Name);
  case "Size Desc": sorted = myquestions.OrderByDescending(x => x.Size);
  default: throw new NotImplementedException();
}
var questions = sorted.Skip(pageIndex * pageSize).Take(pageSize);

你甚至可以添加一个二级排序(或者在它们完全相同之后的任意数量):

IOrderedQueryable<Question> sorted;
switch (sort) {
  case "Id":  sorted = myquestions.OrderBy(x => x.Id);
  case "Name": sorted = myquestions.OrderBy(x => x.Name);
  case "Size": sorted = myquestions.OrderBy(x => x.Size);
  case "Id Desc":  sorted = myquestions.OrderByDescending(x => x.Id);
  case "Name Desc": sorted = myquestions.OrderByDescending(x => x.Name);
  case "Size Desc": sorted = myquestions.OrderByDescending(x => x.Size);
  default: throw new NotImplementedException();
}
switch (sort2) {
  case "Id":  sorted = sorted.ThenBy(x => x.Id);
  case "Name": sorted = sorted.ThenBy(x => x.Name);
  case "Size": sorted = sorted.ThenBy(x => x.Size);
  case "Id Desc":  sorted = sorted.ThenByDescending(x => x.Id);
  case "Name Desc": sorted = sorted.ThenByDescending(x => x.Name);
  case "Size Desc": sorted = sorted.ThenByDescending(x => x.Size);
}
var questions = sorted.Skip(pageIndex * pageSize).Take(pageSize);

答案 1 :(得分:2)

请检查my answer to another question如何使用来自给定OrderBy的{​​{1}}制作自定义Expression谓词。

答案 2 :(得分:2)

巴哈哈,现在我要哭了:

试图实现dtb的解决方案,我看到了问题:

OrderByField<T>(IQueryable<T> q,

输入IQueryable时返回IQueryable ... lol bs。 所以,真正的问题是如何将List转换为iQueryable。

其实,事实上很简单:

var list = new List<T>(); 
var queryable = list.AsQueryable(); 

然后

queryable.OrderBy(sidx + " " + sord);

所以最终的解决方案同样重要:

myquestions.AsQueryable().OrderBy(sidx + " " + sord).Skip(pageIndex * pageSize).Take(pageSize);

这也意味着Linq.Table实现了IQueryable,这是有道理的恕我直言。

编辑:
注意:
这需要引用:Dynamic.dll(不是System.Dynamic.dll) 以及

using System.Linq.Dynamic;

如果您没有引用Dynamic.dll,或者没有声明using指令,那么您将在AsQueryable()上收到错误。

答案 3 :(得分:1)

一种选择是从每个可能的排序字符串到适当的委托创建字典。例如:

Dictionary<string, Func<IEnumerable<Question>, IEnumerable<Question>> orderings =
    new Dictionary<string, Func<IEnumerable<Question>, IEnumerable<Question>>()
{
    { "Id",  questions => questions.OrderBy(x => x.Id) },
    { "Title",  questions => questions.OrderBy(x => x.Title) },
    { "Answer",  questions => questions.OrderBy(x => x.Answer) },
    { "Id Desc",  questions => questions.OrderByDescending(x => x.Id) },
    { "Title Desc",  questions => questions.OrderByDescending(x => x.Title) },
    { "Answer Desc",  questions => questions.OrderByDescending(x => x.Answer) },
};

然后您可以在执行时找到该映射,并应用该函数。

答案 4 :(得分:1)

您可以查看Dynamic Linq。 IIRC这是VS2008附带的样本,如果它仍然包含在VS2010中,我不是100%确定。