泛型方法動態生成表達式樹 Expression


        public string GetGridJSON(TraderInfo model)
        {
            IQueryable<TraderInfo> Temp = db.TraderInfo;
            if (model.LoginAccount != null)
            {
                Temp = Temp.Where(X => X.LoginAccount == model.LoginAccount);
            }
            if (model.ShopName != null)
            {
                Temp = Temp.Where(X => X.ShopName == model.ShopName);
            }
            return JsonConvert.SerializeObject(Temp.ToList(), Formatting.Indented, new JsonSerializerSettings() { DateFormatHandling = 0 });
        }

 

這是MVC 項目。  點擊查詢 執行 GetGridJSON 方法。由於 MVC 規范  name屬性可以匹配 模型,如果 不填寫 賬號 、名稱 ,返回的  model 里面 的 賬號 、名稱屬性為 null。 每次都要判斷 是否 是 null ,如果是 ,就 查詢 所有,否  才能匹配where。

這很不好,如果我的條件 很多 呢?  這樣的判斷  就 很煩了。

我做了如下如下封裝

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Linq.Expressions;

namespace EF_DAL
{
    /// <summary>
    /// 動態生成 表達式樹
    /// </summary>
    public class Custom_Expression
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns>Lambda表達式樹</returns>
        public delegate Expression ExpressionEventHandler(Expression left, Expression right);
        private static BinaryExpression filter = Expression.Equal(Expression.Constant(1), Expression.Constant(1));

        /// <summary>
        /// 自定義Equal方法(允許value為null),value為null 的時候,該查詢條件 不會生成
        /// </summary>
        /// <typeparam name="T">實體數據類型</typeparam>
        /// <param name="columnNames">以逗號分割的列名稱</param>
        /// <param name="values">這些列對應的值</param>
        /// <returns>返回Lambda表達式,eg:where(Lambda)</returns>
        public Expression<Func<T, bool>> Custom_Equal<T>(string columnNames, params object[] values)
        {
            return Custom_Expression_Common<T>(Equal_result, columnNames, values);
        }
        /// <summary>
        /// 初始化where 1=1
        /// </summary>
        private void Init()
        {
            filter = Expression.Equal(Expression.Constant(1), Expression.Constant(1));
        }

        /// <summary>
        /// 自定義Contains方法(允許value為null),value為null 的時候,該查詢條件 不會生成
        /// </summary>
        /// <typeparam name="T">實體數據類型</typeparam>
        /// <param name="columnNames">以逗號分割的列名稱</param>
        /// <param name="values">這些列對應的值</param>
        /// <returns>返回Lambda表達式,eg:where(Lambda)</returns>
        public Expression<Func<T, bool>> Custom_Contain<T>(string columnNames, params object[] values)
        {
            return Custom_Expression_Common<T>(Contains_result, columnNames, values);
        }

        private Expression Contains_result(Expression left, Expression right)
        {
            return Expression.Call(left, typeof(string).GetMethod("Contains"), right);
        }

        private Expression Equal_result(Expression left, Expression right)
        {
            return Expression.Equal(left, right);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Handler">可以是  Equal、Contains</param>
        /// <param name="columnNames"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        private Expression<Func<T, bool>> Custom_Expression_Common<T>(ExpressionEventHandler handler, string columnNames, params object[] values)
        {
            Init();
            var columns = columnNames.Split(',');
            var param = Expression.Parameter(typeof(T));
            for (int i = 0; i < columns.Length; i++)
            {
                if (values[i] == null) continue;
                string columnName = columns[i].ToString();
                var value = values[i];
                Expression left = Expression.Property(param, typeof(T).GetProperty(columnName));
                Expression right = Expression.Constant(value, value.GetType());
                Expression result = handler(left, right);
                filter = Expression.And(filter, result);// where 條件 拼接
            }
            return Expression.Lambda<Func<T, bool>>(filter, param);
        }
    }
}
View Code


直接這樣 調用啦!

 public string GetGridJSON(TraderInfo model)
        {
            EF_DAL.Custom_Expression CE = new EF_DAL.Custom_Expression();
            var traderInfoList = db.TraderInfo.Where(CE.Custom_Equal<TraderInfo>("LoginAccount,ShopName", model.LoginAccount, model.ShopName)).ToList();
            return JsonConvert.SerializeObject(traderInfoList, Formatting.Indented, new JsonSerializerSettings() { DateFormatHandling = 0 });
        }
View Code

 

 期待更好的方法。


免責聲明!

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



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