繁体   English   中英

通过任意排序表达式排序列表?

[英]Order a List by a arbitrary sort expression?

题:

我有一个通用列表,像这样:

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”进行排序。 那可能吗?

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

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

请检查我对有关如何使用给定String Expression构建自定义OrderBy谓词的另一个问题的回答

巴哈哈,现在我要哭了:

尝试实现dtb的解决方案时,我看到了问题所在:

OrderByField<T>(IQueryable<T> q,

输入IQueryable ...时返回IQueryable。 因此,真正的问题是如何将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()上收到错误消息。

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

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

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

您可以看一下Dynamic Linq IIRC是VS2008附带的一个示例,我不确定100%是否仍包含在VS2010中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM