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");
                        }
                    }
                ]
            });

 

posted @ 2017-08-31 16:48  jackchain  阅读(1791)  评论(0编辑  收藏  举报