我正在尝试构建一些代码来动态排序Linq IQueryable <>.
显而易见的方法是在这里,使用字符串字符串对列表进行排序
http://dvanderboom.wordpress.com/2008/12/19/dynamically-composing-linq-orderby-clauses/
但是,我想要一个更改 - 编译字段名称的时间检查,以及使用重构/查找所有引用来支持以后的维护的能力.这意味着我想将字段定义为f => f.Name,而不是字符串.
对于我的具体用途,我想封装一些代码,这些代码将决定应该根据用户输入使用命名的"OrderBy"表达式列表中的哪一个,而不必每次都编写不同的代码.
这是我写的内容的要点:
var list = from m Movies select m; // Get our list
var sorter = list.GetSorter(...); // Pass in some global user settings object
sorter.AddSort("NAME", m=>m.Name);
sorter.AddSort("YEAR", m=>m.Year).ThenBy(m=>m.Year);
list = sorter.GetSortedList();
...
public class Sorter<TSource>
...
public static Sorter<TSource> GetSorter(this IQueryable<TSource> source, ...)
Run Code Online (Sandbox Code Playgroud)
GetSortedList函数确定要使用哪个命名排序,这会产生List对象,其中每个FieldData包含在AddSort中传递的字段的MethodInfo和Type值:
public SorterItem<TSource> AddSort(Func<T, TKey> field)
{
MethodInfo ... = field.Method;
Type ... = TypeOf(TKey);
// Create item, add item to diction, add fields to …Run Code Online (Sandbox Code Playgroud) 我在ASP.NET MVC 3站点中的很多页面中使用数据表.他们使用服务器端分页,现在我想基于列标题实现排序.数据表带有iSortCol_0 哪个是单击列的int值.
我不喜欢这种方法,因为查询最终会像:
if(iSortCol_0 == 0)
{
// query
// OderBy(x => x.CarName)
}
Run Code Online (Sandbox Code Playgroud)
然后对每列重复这一过程(加上每个列的else子句按降序排序).所以我改变了我的方法,现在将列名传递给服务器.
我想出了以下内容:
Expression<Func<vw_Car, string>> sortExpression1 = null;
Expression<Func<vw_Car, int>> sortExpression2 = null;
switch(columnToSort)
{
case "InvoiceNo": sortExpression1 = x => x.CarNo; break;
case "ClientNumber": sortExpression1 = x => x.ForeName; break;
case "ClientName": sortExpression1 = x => x.SurName; break;
default: sortExpression2 = x => x.Age.Value; break;
}
// start of query
.OrderByDir(sortDirection, sortExpression1 , sortExpression2)
Run Code Online (Sandbox Code Playgroud)
现在OrderByDir看起来如下:
public static IOrderedQueryable<T> OrderByDir<T>(this IQueryable<T> source, …Run Code Online (Sandbox Code Playgroud)