• element UI table 过滤 筛选问题、where、orderby重载


    一、问提描述

        使用elementUI table 官方筛选案例,发现筛选不是服务器端筛选,而是浏览器端对每一页进行单独筛选。 如何在服务器端筛选?

     二、查询Element UI 官网table组件发现:

        1、Afilter-change事件,说明:当表格的筛选条件发生变化的时候会触发该事件,参数的值是一个对象,对象的 key 是 column 的 columnKey,对应的 value 为用户选择的筛选条件的数组。参数:filters。

                 2、 prop属性,说明:对应列内容的字段名,也可以使用 property 属性。类型 string

         3、filters属性,说明:数据过滤的选项,数组格式,数组中的元素需要有 text 和 value 属性。类型 Array[{test,value}]

         4、column-key属性,说明:column 的 key,如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件  类型:string

    三、用法描述

     1.在 el-table 标签 @filter-change="handleFilterChange" ,

     2. 在vue周期函数methods: {}中实现 

      handleFilterChange 方法:可以监听整个table中过滤条件变化; --这个事件非常重要,这里它还充当了与服务器进行数据交互的入口。这是过滤方法不能提供的,因为过滤方法逐行执行,执行次数太多。

      setFilter方法:按照服务器api需要的格式组装过滤条件;此处需要在data({returen{ }})中定义一个中间变量this.filter:[] ,用来保存和更新过滤条件。
      getList()方法:发送请求;

       3 在 el-table-column 列中,当以过滤条件 :filters="userStatusNameFilters"、column-key="UserStatusName"、prop="UserStatusName" 三者缺一不可,且column-key的值必须与prop一致,也就是必须为字段名称"。若不定义column-key的值,那么handleFilterChange (filter)返回值filter对象的名称将会是一个自动生成的值。

      4 在data(){return{ userStatusNameFilters: [] }} 定义数组 。如果数据是固定不变的可以在js中直接写入值 serStatusNameFilters: [{text:‘管理员’,value:‘管理员’},{text:‘普通用户’,value:‘普通用户’}] 。如果数据可能有变化,需要从服务器端取值。

    四、代码描述:

    前端代码:

        <el-table
          v-loading="listLoading"
          :key="tableKey"
          :data="list"
          :border="false"
          :stripe="true"
          size="small"
          style=" 100%;"
          @filter-change="handleFilterChange"
    
        >
    
          <el-table-column
            :filters="regionNameFilters"
            column-key="RegionName"
            label="行政区域"
            prop="RegionName"
            align="center"
            width="120px"
          />
    View Code
     methods: {
    
        // 当talbel中任何一列的过滤条件点击确定和覆盖时,都会触发此事件。
        handleFilterChange(filters) {
        //  console.log(filters)
          // console.log('筛选条件发生变化')
          let row = null
          let val = null
          // 拷贝filters的值。
          for (const i in filters) {
            row = i // 保存 column-key的值,如果事先没有为column-key赋值,系统会自动生成一个唯一且恒定的名称
            val = filters[i]
          }
          const filter = [{
            row: row,
            op: 'contains',
            value: val
          }]
          // console.log(filter)
          this.setFilter(filter)
        },
    
        getList() {
          this.listLoading = true
    
          var filters = []
          for (var i in this.filters) {
            // 去除value数组为空的值
            if (this.filters[i].value && this.filters[i].value.length > 0) {
              filters.push({ 'field': this.filters[i].row, 'op': this.filters[i].op, 'value': this.filters[i].value })
            }
          }
    
          if (filters.length > 0) {
            // 将 JavaScript 值(通常为对象或数组)转换为 JSON 字符串
            this.listQuery.filters = JSON.stringify(filters)
          } else {
            this.listQuery.filters = null
          }
    
          this.listQuery.query = this.queryInfo
    
          console.log(filters)
          getList(this.listQuery).then(response => {
            // console.log(response.data.rows);
            this.list = response.data.rows
            this.total = response.data.total
            this.listLoading = false
          })
        },
        // 通过中间变量this.filters数组,保存当前table中所有列过滤条件的变化。
        setFilter(filters) {
          for (var i in filters) {
            var filter = null
            for (var j in this.filters) {
              // 如果filters[i]中存在于this.filter[]相同的值,那么把当前this.filter[i]的引用覆盖filter的引用.
              if (filters[i]['row'] === this.filters[j]['row']) {
                filter = this.filters[j]
              }
            }
            // 如果filter为空,即不存在相同的值,则将当前filter[i]添加到this.filter[]
            if (filter == null) {
              this.filters.push({ 'row': filters[i].row, 'op': filters[i].op, 'value': filters[i].value })
            } else {
              // 如果filter不为空,即存在相同的值。则将filter[i] 赋值给filter,本质是更新this.filter[i]的值。
              filter.value = filters[i].value
              filter.op = filters[i].op
            }
          }
    
          // console.log(this.filters)
          this.listQuery.page = 1
          this.getList()
        },
        getRegionName() {
          getRegionName().then(response => {
            var temp = []
            for (var i = 0; i < response.data.length; i++) {
              temp.push({ text: response.data[i].RegionName, value: response.data[i].RegionName })
            }
            this.regionNameFilters = temp.slice(0)
            // console.log(this.regionNameFilters)
          })
        },
    
    }
    //getList、getRegionName 是对axios异步请求的封装。对应后端的一个api,。
    View Code

     table结合分页显示:

           //element组件   
        <el-pagination
                      :current-page="listQuery.page"
                      :page-sizes="[10,15,20,30, 50]"
                      :disabled="enumLoading"
                      :page-size="listQuery.limit"
                      :total="total"
                      background
                      layout="total, sizes, prev, pager, next, jumper"
                      @size-change="handleSizeChange"
                      @current-change="handleCurrentChange" />
                  </div>
    
        //变量
         total: null, //共多少行数据
       enumLoading: false,
        listQuery: {
            page: 1, //默认从第一页开始
            limit: 15, //默认每页15行
            filters: []  //存储需要过滤字段名称和值
          },
        //方法
        handleSizeChange(val) {
          this.listQuery.limit = val
          this.getList()
        },
        handleCurrentChange(val) {
          this.listQuery.page = val
          this.getList()
        },
    
        
    后端代码(C#、linq实现):
            [HttpGet]
            [Route("List")]
            public ApiResult GetList(int page, int limit, string sort = null, string order = null, string filters = null, string query = null)
            {
                PageModel p = new PageModel();
                if (filters != null)
                {
                    p.filters = Newtonsoft.Json.JsonConvert.DeserializeObject<Filter[]>(filters);
                }
    
                p.page = page;
                p.rows = limit;
                p.sort = sort;
                p.order = order;
    
                if (p.page <= 0)
                {
                    p.page = 1;
                }
                if (p.rows <= 0)
                {
                    p.rows = 10;
                }
    
                var data = manage.GetQueryable().Select(d => d);
                //过滤
                data = data.Where(p.filters);
                //搜索条件
                if (query != null && query.Length > 0)
                {
                    data = data.Where(new string[] { "UserName", "RealName" }, query);
                }
                //排序
                if (order != "normal" && sort != null)
                {
                    bool isAsc = order == "asc";
                    data = data.OrderBy(new[] { sort }, new[] { isAsc });
                }
                else
                {
                    //默认排序
                    data = data.OrderBy(d => d.UserID);
                }
    
                DataModel pageData = new DataModel();
                pageData.page = p.page;
                pageData.total = data.Count();
                pageData.rows = data.Skip((p.page - 1) * p.rows).Take(p.rows).ToList();
    
                ApiResult result = new ApiResult();
                result.success = true;
                result.data = pageData;
                return result;
            }


            [HttpGet]
            [Route("RegionName")]
            public ApiResult GetRegionName()
            {
    
                ApiResult result = new ApiResult();
                result.success = true;
                result.data = manage.GetRegionData().Select(d => new { id = d.RegionID, name = d.RegionName }).ToList();
                return result;
            }

     where orderby  重载

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Web;
    
    namespace PastureSpace.Models
    {
        public static class QueryableExtension
        {
    
            public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string[] propertyName, bool[] ascending) where T : class
            {
                Type type = typeof(T);
    
                for (int i = 0; i < propertyName.Length; i++)
                {
    
                    PropertyInfo property = type.GetProperty(propertyName[i]);
                    if (property == null)
                        throw new ArgumentException("propertyName", "Not Exist");
    
                    ParameterExpression param = Expression.Parameter(type, "p");
                    Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);
                    LambdaExpression orderByExpression = Expression.Lambda(propertyAccessExpression, param);
    
                    string methodName = ascending[i] ? "OrderBy" : "OrderByDescending";
                    if (i != 0)
                    {
                        methodName = ascending[i] ? "ThenBy" : "ThenByDescending";
                    }
    
                    MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName, new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExpression));
                    source = source.Provider.CreateQuery<T>(resultExp);
    
                }
    
    
                return source;
            }
    
    
            public static IQueryable<T> Where<T>(this IQueryable<T> source, FilterRule[] filterRules) where T : class
            {
                if (filterRules == null)
                {
                    return source;
                }
                Type type = typeof(T);
    
                ParameterExpression param = Expression.Parameter(type, "c");
    
                Expression<Func<T, bool>> op = null;
    
                foreach (var rule in filterRules)
                {
                    PropertyInfo property = type.GetProperty(rule.Field);
                    if (property == null)
                    {
                        continue;
                    }
                    //c.Field==Value
                    //c=>c.Field.Contains(Value)
                    Expression left = Expression.Property(param, property);
    
                    Expression right = Expression.Constant(rule.Value);
                    Type valueType = property.PropertyType;
                    if (rule.Value == null || rule.Value == "") continue;
                    DateTime inputDateTime = DateTime.Now;
                    try
                    {
    
                        if (valueType == typeof(int) || valueType == typeof(int?))
                        {
                            right = Expression.Constant(Convert.ToInt32(rule.Value.Split('.')[0]), valueType);
                        }
                        else if (valueType == typeof(short) || valueType == typeof(short?))
                        {
                            right = Expression.Constant(Convert.ToInt16(rule.Value.Split('.')[0]), valueType);
                        }
                        else if (valueType == typeof(byte) || valueType == typeof(byte?))
                        {
                            right = Expression.Constant(Convert.ToByte(rule.Value.Split('.')[0]), valueType);
                        }
                        else if (valueType == typeof(long) || valueType == typeof(long?))
                        {
                            right = Expression.Constant(Convert.ToInt64(rule.Value), valueType);
                        }
                        else if (valueType == typeof(float) || valueType == typeof(float?))
                        {
                            right = Expression.Constant(Convert.ToSingle(rule.Value), valueType);
                        }
                        else if (valueType == typeof(double) || valueType == typeof(double?))
                        {
                            right = Expression.Constant(Convert.ToDouble(rule.Value), valueType);
                        }
                        else if (valueType == typeof(decimal) || valueType == typeof(decimal?))
                        {
                            right = Expression.Constant(Convert.ToDecimal(rule.Value), valueType);
                        }
                        else if (valueType == typeof(DateTime) || valueType == typeof(DateTime?))
                        {
                            inputDateTime = Convert.ToDateTime(rule.Value);
                            right = Expression.Constant(Convert.ToDateTime(rule.Value), valueType);
                        }
                        else if (valueType == typeof(Guid) || valueType == typeof(Guid?))
                        {
                            right = Expression.Constant(Guid.Parse(rule.Value), valueType);
                        }
                        else if (valueType == typeof(bool) || valueType == typeof(bool?))
                        {
                            right = Expression.Constant(Boolean.Parse(rule.Value), valueType);
                        }
    
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        break;
                    }
    
    
                    Expression filter = Expression.Equal(left, right);
                    Expression filter2 = null;
                    MethodInfo method;
    
                    switch (rule.Op)
                    {
                        case OP.contains:
                            //BinaryExpression
                            if (valueType == typeof(string))
                            {
                                method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
                                filter = Expression.Call(left, method, right);
                            }
                            else if (valueType == typeof(DateTime) || valueType == typeof(DateTime?))
                            {
                                right = Expression.Constant(inputDateTime.Date);
                                filter = Expression.GreaterThanOrEqual(left, right);
                                right = Expression.Constant(inputDateTime.Date.AddDays(1));
                                filter2 = Expression.LessThan(left, right);
                            }
                            else
                            {
                                filter = Expression.Equal(left, right);
                            }
                            break;
                        case OP.equal:
                            filter = Expression.Equal(left, right);
                            break;
                        case OP.notequal:
                            filter = Expression.NotEqual(left, right);
                            break;
                        case OP.beginwith:
                            method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
    
                            filter = Expression.Call(left, method, right);
                            break;
                        case OP.endwith:
                            method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
    
                            filter = Expression.Call(left, method, right);
                            break;
                        case OP.less:
                            filter = Expression.LessThan(left, right);
                            break;
                        case OP.lessorequal:
                            filter = Expression.LessThanOrEqual(left, right);
                            break;
                        case OP.greater:
                            filter = Expression.GreaterThan(left, right);
                            break;
                        case OP.greaterorequal:
                            filter = Expression.GreaterThanOrEqual(left, right);
                            break;
                        default:
                            break;
                    }
    
    
    
                    var lambda = Expression.Lambda<Func<T, bool>>(filter, param);
                    if (op == null)
                    {
                        op = lambda;
                    }
                    else
                    {
                        op = Expression.Lambda<Func<T, bool>>(Expression.And(op.Body, lambda.Body), op.Parameters);
                    }
    
                    if (filter2 != null)
                    {
                        var lambda2 = Expression.Lambda<Func<T, bool>>(filter2, param);
                        op = Expression.Lambda<Func<T, bool>>(Expression.And(op.Body, lambda2.Body), op.Parameters);
                    }
                }
    
                if (op != null)
                {
                    source = source.Where(op);
                }
                return source;
            }
    
            /// <summary>
            ///  多条件过滤
            /// </summary>
            /// <typeparam name="T">泛型,默认传入类名</typeparam>
            /// <param name="source">默认传入where前的IQueryable语句</param>
            /// <param name="filters">存放一或多个过滤条件的数组</param>
            /// <returns></returns>
            public static IQueryable<T> Where<T>(this IQueryable<T> source, Filter[] filters) where T : class
            {
                //检查过滤条件是否存在,不存在则返回where前的IQueryable语句
                if (filters == null)
                {
                    return source;
                }
                //获取类型
                Type type = typeof(T);
    
                ParameterExpression param = Expression.Parameter(type, "c");
    
                Expression<Func<T, bool>> op = null;
    
    
                foreach (var rule in filters)
                {
                    PropertyInfo property = type.GetProperty(rule.Field);
                    if (property == null)
                    {
                        continue;
                    }
                    //c.Field==Value
                    //c=>(c.Field.Contains(Value) || c.Field.Contains(Value))
                    Exception outExc = new Exception();
    
                    Expression left = Expression.Property(param, property);
                    Type valueType = property.PropertyType;
                    if (rule.Value == null || rule.Value.Length <= 0) continue;
                    
                    Expression<Func<T, bool>> lambdaOut = null;
                    foreach (var v in rule.Value)
                    {
                        if (v == null || v == "") continue;
                        Expression right = Expression.Constant(v);
                        DateTime inputDateTime = DateTime.Now;
                        try
                        {
    
                            if (valueType == typeof(int) || valueType == typeof(int?))
                            {
                                right = Expression.Constant(Convert.ToInt32(v.Split('.')[0]), valueType);
                            }
                            else if (valueType == typeof(short) || valueType == typeof(short?))
                            {
                                right = Expression.Constant(Convert.ToInt16(v.Split('.')[0]), valueType);
                            }
                            else if (valueType == typeof(byte) || valueType == typeof(byte?))
                            {
                                right = Expression.Constant(Convert.ToByte(v.Split('.')[0]), valueType);
                            }
                            else if (valueType == typeof(long) || valueType == typeof(long?))
                            {
                                right = Expression.Constant(Convert.ToInt64(v), valueType);
                            }
                            else if (valueType == typeof(float) || valueType == typeof(float?))
                            {
                                right = Expression.Constant(Convert.ToSingle(v), valueType);
                            }
                            else if (valueType == typeof(double) || valueType == typeof(double?))
                            {
                                right = Expression.Constant(Convert.ToDouble(v), valueType);
                            }
                            else if (valueType == typeof(decimal) || valueType == typeof(decimal?))
                            {
                                right = Expression.Constant(Convert.ToDecimal(v), valueType);
                            }
                            else if (valueType == typeof(DateTime) || valueType == typeof(DateTime?))
                            {
                                inputDateTime = Convert.ToDateTime(v);
                                right = Expression.Constant(Convert.ToDateTime(v), valueType);
                            }
                            else if (valueType == typeof(Guid) || valueType == typeof(Guid?))
                            {
                                right = Expression.Constant(Guid.Parse(v), valueType);
                            }
                            else if (valueType == typeof(bool) || valueType == typeof(bool?))
                            {
                                right = Expression.Constant(Boolean.Parse(v), valueType);
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                            break;
                        }
    
    
                        Expression filter = Expression.Equal(left, right);
                        Expression filter2 = null;
                        MethodInfo method;
    
                        switch (rule.Op)
                        {
                            case OP.contains:
                                //BinaryExpression
                                if (valueType == typeof(string))
                                {
                                    method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
                                    filter = Expression.Call(left, method, right);
                                }
                                else if (valueType == typeof(DateTime) || valueType == typeof(DateTime?))
                                {
                                    right = Expression.Constant(inputDateTime.Date);
                                    filter = Expression.GreaterThanOrEqual(left, right);
                                    right = Expression.Constant(inputDateTime.Date.AddDays(1));
                                    filter2 = Expression.LessThan(left, right);
                                }
                                else
                                {
                                    filter = Expression.Equal(left, right);
                                }
                                break;
                            case OP.equal:
                                filter = Expression.Equal(left, right);
                                break;
                            case OP.notequal:
                                filter = Expression.NotEqual(left, right);
                                break;
                            case OP.beginwith:
                                method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
    
                                filter = Expression.Call(left, method, right);
                                break;
                            case OP.endwith:
                                method = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
    
                                filter = Expression.Call(left, method, right);
                                break;
                            case OP.less:
                                filter = Expression.LessThan(left, right);
                                break;
                            case OP.lessorequal:
                                filter = Expression.LessThanOrEqual(left, right);
                                break;
                            case OP.greater:
                                filter = Expression.GreaterThan(left, right);
                                break;
                            case OP.greaterorequal:
                                filter = Expression.GreaterThanOrEqual(left, right);
                                break;
                            default:
                                break;
                        }
    
    
    
                        var lambda = Expression.Lambda<Func<T, bool>>(filter, param);
                        if (lambdaOut == null)
                        {
                            lambdaOut = lambda;
                        }
                        else
                        {
                            lambdaOut = Expression.Lambda<Func<T, bool>>(Expression.Or(lambdaOut.Body, lambda.Body), lambdaOut.Parameters);
                        }
    
                        if (filter2 != null)
                        {
                            var lambda2 = Expression.Lambda<Func<T, bool>>(filter2, param);
                            lambdaOut = Expression.Lambda<Func<T, bool>>(Expression.And(lambdaOut.Body, lambda2.Body), lambdaOut.Parameters);
                        }
                    }
    
                    if (rule.Op == OP.range && rule.Value != null && rule.Value.Length == 2)
                    {
                        if (!(rule.Value[0] == null || rule.Value[0] == "") && !(rule.Value[1] == null || rule.Value[1] == ""))
                        {
                            Expression right1 = Expression.Constant(rule.Value[0]);
                            Expression right2 = Expression.Constant(rule.Value[1]);
                            try
                            {
    
                                if (valueType == typeof(int) || valueType == typeof(int?))
                                {
                                    right1 = Expression.Constant(Convert.ToInt32(rule.Value[0].Split('.')[0]), valueType);
                                    right2 = Expression.Constant(Convert.ToInt32(rule.Value[1].Split('.')[0]), valueType);
                                }
                                else if (valueType == typeof(short) || valueType == typeof(short?))
                                {
                                    right1 = Expression.Constant(Convert.ToInt16(rule.Value[0].Split('.')[0]), valueType);
                                    right2 = Expression.Constant(Convert.ToInt16(rule.Value[1].Split('.')[0]), valueType);
                                }
                                else if (valueType == typeof(byte) || valueType == typeof(byte?))
                                {
                                    right1 = Expression.Constant(Convert.ToByte(rule.Value[0].Split('.')[0]), valueType);
                                    right2 = Expression.Constant(Convert.ToByte(rule.Value[1].Split('.')[0]), valueType);
                                }
                                else if (valueType == typeof(long) || valueType == typeof(long?))
                                {
                                    right1 = Expression.Constant(Convert.ToInt64(rule.Value[0]), valueType);
                                    right2 = Expression.Constant(Convert.ToInt64(rule.Value[1]), valueType);
                                }
                                else if (valueType == typeof(float) || valueType == typeof(float?))
                                {
                                    right1 = Expression.Constant(Convert.ToSingle(rule.Value[0]), valueType);
                                    right2 = Expression.Constant(Convert.ToSingle(rule.Value[1]), valueType);
                                }
                                else if (valueType == typeof(double) || valueType == typeof(double?))
                                {
                                    right1 = Expression.Constant(Convert.ToDouble(rule.Value[0]), valueType);
                                    right2 = Expression.Constant(Convert.ToDouble(rule.Value[1]), valueType);
                                }
                                else if (valueType == typeof(decimal) || valueType == typeof(decimal?))
                                {
                                    right1 = Expression.Constant(Convert.ToDecimal(rule.Value[0]), valueType);
                                    right2 = Expression.Constant(Convert.ToDecimal(rule.Value[1]), valueType);
                                }
                                else if (valueType == typeof(DateTime) || valueType == typeof(DateTime?))
                                {
                                    right1 = Expression.Constant(Convert.ToDateTime(rule.Value[0]), valueType);
                                    right2 = Expression.Constant(Convert.ToDateTime(rule.Value[1]), valueType);
                                }
                                else if (valueType == typeof(Guid) || valueType == typeof(Guid?))
                                {
                                    right1 = Expression.Constant(Guid.Parse(rule.Value[0]), valueType);
                                    right2 = Expression.Constant(Guid.Parse(rule.Value[0]), valueType);
                                }
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                                break;
                            }
    
    
                            Expression filter = Expression.GreaterThanOrEqual(left, right1);
                            Expression filter2 = Expression.LessThanOrEqual(left, right2);
    
    
                            var lambda = Expression.Lambda<Func<T, bool>>(filter, param);
                            if (lambdaOut == null)
                            {
                                lambdaOut = lambda;
                            }
                            else
                            {
                                lambdaOut = Expression.Lambda<Func<T, bool>>(Expression.Or(lambdaOut.Body, lambda.Body), lambdaOut.Parameters);
                            }
    
                            if (filter2 != null)
                            {
                                var lambda2 = Expression.Lambda<Func<T, bool>>(filter2, param);
                                lambdaOut = Expression.Lambda<Func<T, bool>>(Expression.And(lambdaOut.Body, lambda2.Body), lambdaOut.Parameters);
                            }
                        }
    
                    }
    
                    if (op == null)
                    {
                        op = lambdaOut;
                    }
                    else
                    {
                        if (lambdaOut != null)
                        {
                            op = Expression.Lambda<Func<T, bool>>(Expression.And(op.Body, lambdaOut.Body), op.Parameters);
                        }
                    }
    
    
                }
                if (op != null)
                {
                    source = source.Where(op);
                }
                return source;
    
            }
    
            /// <summary>
            ///  仅查询string类型数据
            /// </summary>
            /// <typeparam name="T">泛型,默认传入类名</typeparam>
            /// <param name="source">默认传入where前的IQueryable语句</param>
            /// <param name="columnNames">存放待查询列名称的数组</param>
            /// <param name="filterString">查询内容</param>
            /// <returns></returns>
            public static IQueryable<T> Where<T>(this IQueryable<T> source, string[] columnNames, string filterString)
            {
                //获取覆盖当前泛型的类型
                Type type = typeof(T);
                //构建表达式树的参数c
                ParameterExpression param = Expression.Parameter(type, "c");
                //构建一个表达式树节点,存放查询内容
                Expression right = Expression.Constant(filterString);
    
                //1!=1
                //Expression op = Expression.NotEqual(Expression.Constant(1), Expression.Constant(1));
                //构建一个存放lamdba表达式树的空对象
                Expression<Func<T, bool>> op = null;
    
                //循环遍历存放查询列的数组
                foreach (var column in columnNames)
                {
                    //反射获取该列对应属性的类型
                    PropertyInfo property = type.GetProperty(column);
                    //如果不存在该属性则结束本次循环,进入下次循环
                    if (property == null)
                    {
                        continue;
                    }
                    //c.Field==Value
                    //c=>c.Field.Contains(Value)
                    //构建一个表示访问属性的表达式树c=>c.Field
                    Expression left = Expression.Property(param, property);
    
                    //获取属性类型
                    Type valueType = property.PropertyType;
                    //若属性类型不为string类型,则结束本次循环
                    if (valueType != typeof(string)) continue;
                    //若属性值等于null或字符串长度为0,则结束本次循环
                    if (filterString == null || filterString == "") continue;
    
                    //通过反射获取string类型的Contains方法
                    MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
    
                    //构建一个表示调用参数的方法 c=>c.Field.Contains(Value)
                    Expression filter = Expression.Call(left, method, right);
    
                    //将表达式转换为lambda表达式
                    var lambda = Expression.Lambda<Func<T, bool>>(filter, param);
                    if (op == null)
                    {
                        //将构建好的lambda表达式赋值给op对象
                        op = lambda;
                    }
                    else
                    {
                        // 若op非空,则以or形式追加本次lambda表达式到op对象
                        op = Expression.Lambda<Func<T, bool>>(Expression.Or(op.Body, lambda.Body), op.Parameters);
                    }
                }
    
                if (op != null)
                {
                    //如果op不为空,则输出合并后的语句
                    source = source.Where(op);
                }
                return source;
            }
        }
    }
    

     

     Filter、OP模型类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    namespace PastureSpace.Models
    {
        public class FilterRule
        {
            public string Field { get; set; }
    
            public OP Op { get; set; }
    
            public string Value { get; set; }
        }
    
    
        public class Filter
        {
            public string Field { get; set; }
    
            public OP Op { get; set; }
    
            public string[] Value { get; set; }
        }
    
        public enum OP
        {
            contains, equal, notequal, beginwith, endwith, less, lessorequal, greater, greaterorequal, range
        }
    }
    

     pageMode模型类

        public class PageModel
        {
            public int Page { get; set; }
    
            public int Rows { get; set; }
    
            public string Sort { get; set; }
    
            public string Order { get; set; }
    
            public string FilterRules { get; set; }
            public List<FilterRule> FilterRuleList
            {
                get
                {
                    if (FilterRules == null) return null;
                    return JsonConvert.DeserializeObject<List<FilterRule>>(FilterRules);
                }
            }
    
        }
    View Code

    ApiResult 模型类

        public class ApiResult
        {
            public bool success { get; set; }
    
            public string msg { get; set; }
    
            public object data { get; set; }
        }
    View Code

       以上代码是从实际项目截取出来的并不是完整的Demo,实际项目测试可行,如有问题请留言。

     核心是  从前端element table几个方法获取筛选条件 , 服务器端where orderby 重载实现多条件筛选和排序。

  • 相关阅读:
    0015 Java学习笔记-集合-TreeMap集合
    0014 Java学习笔记-集合-HashMap集合
    0013 Java学习笔记-面向对象-static、静态变量、静态方法、静态块、单例类
    0012 win7x64安装CentOS7
    0011《SQL必知必会》笔记07 数据的插入、更新和删除
    0010《SQL必知必会》笔记06-表的修改与删除
    0009《SQL必知必会》笔记05-表的创建与约束
    0008《SQL必知必会》笔记04-子查询、联接与组合查询
    0007《SQL必知必会》笔记03-汇总与分组数据
    0006 《SQL必知必会》笔记02-计算字段与函数
  • 原文地址:https://www.cnblogs.com/hao-1234-1234/p/9647322.html
Copyright © 2020-2023  润新知