EntityFramework 动态构造排序 Func<IQueryable<T>, IOrderedQueryable<T>> Dynamic
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; /** * * jackchain * QQ:710782046 * 2017-08-31 * 动态构造OrderBy Linq序列 * */ namespace UFX.Tools { public class ConvertExtOrderLinq { /// <summary> /// 动态转换为Linq排序 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="orderList">[aaa,bbb,ccc],[asc,asc,desc]</param> /// <returns></returns> public static Func<IQueryable<T>, IOrderedQueryable<T>> GetOrderBy<T>(List<string> orderColumn, List<string> orderDir) { string ascKey = "OrderBy"; string descKey = "OrderByDescending"; Type typeQueryable = typeof(IQueryable<T>); ParameterExpression argQueryable = Expression.Parameter(typeQueryable, "jk"); var outerExpression = Expression.Lambda(argQueryable, argQueryable); for (int i = 0; i < orderColumn.Count; i++) { string columnName = orderColumn[i]; string dirKey = orderDir[i].ToLower(); IQueryable<T> query = new List<T>().AsQueryable<T>(); Type type = typeof(T); ParameterExpression arg = Expression.Parameter(type, "uf"); Expression expr = arg; if (columnName.Contains(".")) { // support to be sorted on child fields. String[] childProperties = columnName.Split('.'); System.Reflection.PropertyInfo property = typeof(T).GetProperty(childProperties[0]); MemberExpression propertyAccess = Expression.MakeMemberAccess(arg, property); for (int j = 1; j < childProperties.Length; j++) { Type t = property.PropertyType; if (!t.IsGenericType) { property = t.GetProperty(childProperties[j]); } else { property = t.GetGenericArguments().First().GetProperty(childProperties[i]); } type = property.PropertyType; expr = Expression.MakeMemberAccess(propertyAccess, property); //propertyAccess = Expression.MakeMemberAccess(propertyAccess, property); } //property = type.GetProperty(propertyName); //propertyAccess = Expression.MakeMemberAccess(parameter, property); } else { PropertyInfo pi = type.GetProperty(columnName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); expr = Expression.Property(expr, pi); type = pi.PropertyType; } LambdaExpression lambda = Expression.Lambda(expr, arg); string methodName = dirKey == "asc" ? ascKey : descKey; MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName, new Type[] { typeof(T), type }, outerExpression.Body, Expression.Quote(lambda)); outerExpression = Expression.Lambda(resultExp, argQueryable); ascKey = "ThenBy"; descKey = "ThenByDescending"; } return (Func<IQueryable<T>, IOrderedQueryable<T>>)outerExpression.Compile(); } } }
如何使用?
[Action] [Description("获取Grid数据")] [HttpPost] public JsonResult Get(int start, int length, ExtGridSearch condition, ExtGridMutiSearch[] extCdns, ExtGridOrder[] order) { int totalCount = 0; Func<IQueryable<DB_Color>, IOrderedQueryable<DB_Color>> dyncOrder = ConvertExtOrderLinq.GetOrderBy<DB_Color>(order.Select(s => s.column).ToList(), order.Select(s => s.dir).ToList()); var list = WMFactory.DBColor.FindByPage(start, length, out totalCount, dyncOrder, null, condition, extCdns); return Json(new { data = list, recordsTotal = totalCount, recordsFiltered = totalCount }, JsonRequestBehavior.AllowGet); }
可结合Datatables 插件一起配合使用
//主表格 var DBRangeGrid = $('#DBRangeGrid').dataTable( { scrollY: Global_MainTableHeight, scrollX: true, autoWidth: true, scrollCollapse: false, "processing": true, "serverSide": true, "ajax": { "url": "/Admin/Range/Get", "type": "POST", "data": function (d) { var dtCols = $('#DBRangeGrid').DataTable().settings().init().columns; var extOrder = []; var dtOrders = $('#DBRangeGrid').DataTable().order(); $.each(dtOrders, function (i, item) { extOrder.push({ column: dtCols[item[0]].data, dir: item[1] }); }) d.order = extOrder; d.query = $("#txtSearchKey").val(); d.fields = ['IsEnable', 'Year.YearName', 'Season.SeasonName', 'RangeName', 'Remark', 'CreateUser', ]; } }, "ordering": true, "order": [[8, "desc"]], "columns": [ { "class": "cbcenter", "orderable": false, "title": '<input type="checkbox" title="全选" class="selectAll" />', "data": "Id", "width": "30px", "render": function (data, type, row) { return '<input type="checkbox" class="ckbox" />'; } }, { "title": "启用", "data": "IsEnable", render: function (data, tp, row) { if (row.IsEnable == 1) { return "<span style='color:green'>启用</span>"; } else { return "<span style='color:red'>禁用</span>"; } } }, { "title": "年份", "data": "Year.YearName" }, { "title": "季节", "data": "Season.SeasonName" }, { "title": "月份", "data": "Month" }, { "title": "波段名称", "data": "RangeName" }, { "title": "备注", "data": "Remark" }, { "data": "CreateUser", "title": "操作人", "width": "40px", "render": function (data, type, record) { if (record.ModifyUser != undefined && record.ModifyUser != "" && record.ModifyUser != null) return record.ModifyUser; else return data; } }, { "data": "CreateTime", "title": "操作时间", "width": "120px", "render": function (data, type, record) { if (record.ModifyTime != undefined && record.ModifyTime != "" && record.ModifyTime != null) data = record.ModifyTime; var dt = eval("new " + data.substr(1, data.length - 2)); return dt.Format("yyyy-MM-dd hh:mm:ss"); } } ] });