在跟进一个MVC项目的后台数据显示,用户希望能点击表头来进行数据排序。虽然这个功能说简单也算简单,就一个Order by 完事;但因为其是使用EF的官方类作为数据调用,所以如果在原有的上改涉及到太多;并且其需要的是动态的排序。直接粗暴的做法就是根据其返还的排序字段进行排序。。
代码语言:javascript复制if (pager.order == "desc")
{
switch (pager.order)
{
case "CreateTime":
queryData = queryData.OrderByDescending(c => c.CreateTime);
break;
case "Name":
queryData = queryData.OrderByDescending(c => c.Name);
break;
default:
queryData = queryData.OrderByDescending(c => c.CreateTime);
break;
}
}
else
{
switch (pager.order)
{
case "CreateTime":
queryData = queryData.OrderBy(c => c.CreateTime);
break;
case "Name":
queryData = queryData.OrderBy(c => c.Name);
break;
default:
queryData = queryData.OrderBy(c => c.CreateTime);
break;
}
}
直接粗暴的做法,但这样工作量有点大咯,不是俺的首选。。
于是想通过重写或构建Order来进行排序。
代码语言:javascript复制 public static class MyTools
{
public static IQueryable<TSource> MyOrderBy<TSource>(this IQueryable<TSource> source, string sort, string sortway)
{
if (!string.IsNullOrEmpty(sort))
{
//首先要拿到排序字段的类型
Type type = typeof(TSource).GetProperty(sort).PropertyType;
//如果直接调用处理升序或者降序的方法,参数类型还是无法传递过来
//例如:DealAsc(TSource,type);
//虽然type取到的是参数类型,但是type作为变量,不能直接传递过去
//所以,我们可以用反射调用方法来实现,这样可以动态传递参数类型
//1、先用反射拿到方法
var mothed = typeof(MyTools).GetMethod(sortway=="asc"? "DealAsc":"DealDesc");
//2、给方法传递类型
mothed = mothed.MakeGenericMethod(typeof(TSource), type);
//3、调用方法
IQueryable<TSource> result = (IQueryable<TSource>)mothed.Invoke(null, new object[] { source, sort });
return result;
}
return source;
}
/// <summary>
/// 处理升序的方法
/// </summary>
public static IQueryable<TSource> DealAsc<TSource, M>(this IQueryable<TSource> source, string sort)
{
//生成lamdba表达式
Expression<Func<TSource, M>> lamdba = CreateLamdba<TSource, M>(source, sort);
source = source.OrderBy(lamdba);
return source;
}
/// <summary>
/// 处理降序的方法
/// </summary>
public static IQueryable<TSource> DealDesc<TSource, M>(this IQueryable<TSource> source, string sort)
{
//生成lamdba表达式
Expression<Func<TSource, M>> lamdba = CreateLamdba<TSource, M>(source, sort);
source = source.OrderByDescending(lamdba);
return source;
}
/// <summary>
/// 生成Lamdba表达式
/// </summary>
static Expression<Func<TSource, M>> CreateLamdba<TSource, M>(this IQueryable<TSource> source, string sort)
{
var parame = Expression.Parameter(typeof(TSource), "a");
var body = Expression.Property(parame, sort);
//生成lamdba表达式
Expression<Func<TSource, M>> lamdba = Expression.Lambda<Func<TSource, M>>(body, parame);
return lamdba;
}
}
通过表达式树来,这样好像有点繁琐;也不好维护,后来发现有System.Linq.Dynamic,这个好家伙,不用太复杂代码,简直是简傻瓜式使用,好吧那就直接用。
代码语言:javascript复制 string _order = string.IsNullOrEmpty(pagination.sidx) ? "ID" : pagination.sidx, _sord = pagination.sord;
var orderExpression = string.Format("{0} {1}", _order, _sord);
var Data_List = Data_DAL.GetPagedList(pagination.page, pagination.rows, ref rowCount, zwhere, b => b.CreateDt, isAsc).OrderBy(orderExpression).ToList();
搞掂,就这么简单直接。哦,有一点要注意的就是System.Linq.Dynamic安装时要选择对应的版本,不可以乱装。。
好吧,今天就分享到这里。。