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="width: 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 重載實現多條件篩選和排序。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM