实现动态排序

/// <summary>
/// 实现动态排序
/// 来源博客园的一个大神,具体实现原理是利用实体和排序字段自动生成一个表达式
/// 再利用IQuerable的方法实现
/// 有一部分比较像微软的源码 ZhangQC 2016.10.20
/// </summary>
public static class DynamicOrder
{
#region Private 表达式树
/// <summary>
/// 构建表达式树 结果类似于 j=>j.Name
/// </summary>ZhangQc 2016.10.20
/// <typeparam name="TEntity"></typeparam>
/// <param name="propertyName"></param>
/// <param name="resultType"></param>
/// <returns></returns>
private static LambdaExpression GenerateSelector<TEntity>(String propertyName, out Type resultType) where TEntity : class
{
PropertyInfo property;
Expression propertyAccess;
var parameter = Expression.Parameter(typeof(TEntity), "j");

if (propertyName.Contains(‘.‘))
{
String[] childProperties = propertyName.Split(‘.‘);
property = typeof(TEntity).GetProperty(childProperties[0]);
propertyAccess = Expression.MakeMemberAccess(parameter, property);
for (int i = 1; i < childProperties.Length; i++)
{
property = property.PropertyType.GetProperty(childProperties[i]);
propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
}
}
else
{
property = typeof(TEntity).GetProperty(propertyName);
propertyAccess = Expression.MakeMemberAccess(parameter, property);
}

resultType = property.PropertyType;

return Expression.Lambda(propertyAccess, parameter);
}

/// <summary>
/// 生成方法调用
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="source"></param>
/// <param name="methodName"></param>
/// <param name="fieldName"></param>
/// <returns></returns>
private static MethodCallExpression GenerateMethodCall<TEntity>(IQueryable<TEntity> source, string methodName, String fieldName) where TEntity : class
{
Type type = typeof(TEntity);
Type selectorResultType;
LambdaExpression selector = GenerateSelector<TEntity>(fieldName, out selectorResultType);
MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,
new Type[] { type, selectorResultType },
source.Expression, Expression.Quote(selector));
return resultExp;
}
#endregion

public static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string fieldName) where TEntity : class
{
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "OrderBy", fieldName);
return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
}

public static IOrderedQueryable<TEntity> OrderByDescending<TEntity>(this IQueryable<TEntity> source, string fieldName) where TEntity : class
{
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "OrderByDescending", fieldName);
return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
}

public static IOrderedQueryable<TEntity> ThenBy<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName) where TEntity : class
{
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "ThenBy", fieldName);
return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
}

public static IOrderedQueryable<TEntity> ThenByDescending<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName) where TEntity : class
{
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "ThenByDescending", fieldName);
return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
}
public static IOrderedQueryable<TEntity> OrderUsingSortExpression<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class
{
String[] orderFields = sortExpression.Split(‘,‘);
IOrderedQueryable<TEntity> result = null;
for (int currentFieldIndex = 0; currentFieldIndex < orderFields.Length; currentFieldIndex++)
{
String[] expressionPart = orderFields[currentFieldIndex].Trim().Split(‘ ‘);
String sortField = expressionPart[0];
Boolean sortDescending = (expressionPart.Length == 2) && (expressionPart[1].Equals("DESC", StringComparison.OrdinalIgnoreCase));
if (sortDescending)
{
result = currentFieldIndex == 0 ? source.OrderByDescending(sortField) : result.ThenByDescending(sortField);
}
else
{
result = currentFieldIndex == 0 ? source.OrderBy(sortField) : result.ThenBy(sortField);
}
}
return result;
}

//使用方法
// var query = (from d in ((VinnoTech.Gaia2.DB.g2_dsource[])result)
// join p in WebApiApplication.entities.g2_propnames
// on d.dsource_item equals p.prop_name
// orderby sidx
// select new
// {
// d.dsource_id,
// d.dsource_name,
// dsource_item = p.prop_description,
// d.dsource_description,
// dsource_status = d.dsource_status == "1" ? "启用" : "禁用",
// d.dsource_expiredday,
// dsource_alarmhigh = (d.dsource_alarmhigh == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
// dsource_alarmlow = (d.dsource_alarmlow == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
// dsource_alarmdeltadata = (d.dsource_alarmdeltadata == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
// dsource_alarmidle = (d.dsource_alarmidle == -65535 || d.dsource_alarmhigh == 65535) ? "未禁用" : d.dsource_alarmhigh.ToString(),
// d.dsource_formula,
// dsource_updatetime = d.dsource_updatetime.ToString("yyyy-MM-dd HH:mm:ss")
// }).AsQueryable();

//page = page <= query.Count() / rows + 1 ? page : 1;

//query = query.OrderUsingSortExpression("dsource_name asc,dsource_item desc").Skip(rows * (page - 1)).Take(rows);
}

时间: 2024-10-25 18:20:28

实现动态排序的相关文章

函数指针、回调、动态排序、返回函数指针

1.函数指针定义及初始化: int (*p)(int,int)=NULL; p=maxValue;//将函数maxValue的地址传给p 或 (*p)=maxValue; 2.函数回调: int getValue(int a,int b,int (*p)(int,int));//函数指针作为getValue的参数 函数指针指向函数可变 3.动态排序(排序条件多变) 将决定排序方式的条件封装成函数,然后再回调 typedef BOOL (*P_Fun)(int,int);//头文件#include

解析---DragGridView长按动态排序

曾经项目需求,要实现一个类似以前ZAKER新闻阅读的DragGridView特效.不过,没要求实现横向跨屏,而是竖向跨屏.网上资源也很多,有实现横向跨屏的,可是没有找到竖向的.后来只好结合人家代码,修改一二. 贴代码! /** * @blog http://blog.csdn.net/xiaanming * * @author xiaanming&&wangxuanao * */ public class DragGridView extends GridView { /** * Drag

ActiveReports 报表应用教程 (9)---交互式报表之动态排序

原文:ActiveReports 报表应用教程 (9)---交互式报表之动态排序 在 ActiveReports 中除了提供对数据源进行排序的功能之外,还提供了最终用户排序功能,最终用户可以对报表进行区域内排序和整个数据源排序,结合数据钻取.过滤等功能可以让用户更方便地分析报表数据. 1.创建报表文件 在应用程序中创建一个名为 rptProductListForSort.rdlx 的 ActiveReports 报表文件,使用的项目模板为 ActiveReports 页面报表,创建完成之后从 V

php sortable 动态排序

php sortable 动态排序未分页版.php 预览图: <?php mysql_connect("localhost","root","root"); mysql_select_db("test"); mysql_query("SET CHARACTER SET GB2312"); if($_POST["reorder"]){ $i=1; foreach ($_POST[&q

利用动态排序,对学生结构体的各类信息进行排序

#import <Foundation/Foundation.h> //创建一个学生变量 typedef struct student{ char name[20];  //姓名 int  age;       //年龄 float  weight;  //体重 float  height;  //身高 float  score;   //分数 }Stu; //为什么使用动态排序,动态排序的好处:所有的排序函数if语句之后的比较条件不一样,其余的所有代码都是相同的,把相同的内容放在一个函数里,

Linq To Entities中的动态排序

换了工作有一个月了,一样的工作.一样的代码.一样的体力活仍就-- Linq To Entityes 也是不新玩意了,近半年来也一直与之打交道,但一直也没对其深究过.今天新加的功能要对所有列支持排序,这也不是什么高难度的工作了,对与TSQL来说是写过几百遍了,但在Linq To Enitities中有点小恶心. Linq To Entityes中的对象是个Queryable类型的,Queryable.OrderBy()方法的参数是一个Lamdba source.OrderBy(t=>t.ID).S

使用Linq动态排序

Linq排序很方便,如果能动态创建Expression再排序就更方便了. 正序还是倒序排列 var order = typeof(Enumerable).GetMember(direction == ListSortDirection.Ascending ? "OrderBy" : "OrderByDescending") .First() as MethodInfo;order = order.MakeGenericMethod(typeof(T), typeof

构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(17)-LinQ动态排序

首先修复程序中的一个BUG这个BUG在GridPager类中,把sord修改为sort这个名称填写错误,会导致后台一直无法获取datagrid的排序字段 本来是没有这一讲的,为了使20行的代码精简成2行,我查阅了一些资料,借鉴了一些大神的建议,首先感谢第八讲中,11楼@nyth和15楼@红颜醉丶帝的建议投递,每一次的的排序要都一个判断这的确很麻烦,我们利用反射来解决这个问题. 先看原来的代码 //排序 if (pager.order == "desc") { switch (pager

Ax Grid 的显示根据用户的需求动态排序。

点击方向按钮上下移动记录. 设计思路. 以临时表TmpTable1举例. 在表中加一个real类型字段(eg:ColumnSeq)用于排序,给表建一个ColumnSeq字段的索引ColumnSeqIdx. 在Form的数据源中设置index属性:ColumnSeqIdx. 这样Grid显示数据就会根据ColumnSeq排序. 在form init 临时表数据时,ColumnSeq为一个累加值. 当点击上移记录按钮的时候,倒序TmpTable1的ColumnSeq,大于当前行ColumnSeq,取