表達式樹的說明與運用

来源:https://www.cnblogs.com/just0ne/archive/2019/09/19/11553064.html
-Advertisement-
Play Games

說明: 在我們日常代碼開發中很多的地方都用到了Lambda表達式進行過濾操作,我們很多優秀的ORM也是使用表達式來進行數據的查詢。但是對於一些複雜的過 濾單純的使用Lambda已經不能夠解決問題了那麼就需要表達式樹來進行條件的一個拼接。 下麵介紹一個本人寫的一個工具類有助於項目中更好的使用: 以上就 ...


說明: 在我們日常代碼開發中很多的地方都用到了Lambda表達式進行過濾操作,我們很多優秀的ORM也是使用表達式來進行數據的查詢。但是對於一些複雜的過 濾單純的使用Lambda已經不能夠解決問題了那麼就需要表達式樹來進行條件的一個拼接。 

下麵介紹一個本人寫的一個工具類有助於項目中更好的使用:

  1   public static class ExpressionTreeTools
  2     {
  3         /// <summary>
  4         /// 相當於&&操作
  5         /// ——just0ne
  6         /// </summary>
  7         /// <param name="thisFilter">已生成的過濾條件</param>
  8         /// <param name="otherFilter">未生成的過濾條件</param>
  9         /// <returns>新的過濾</returns>
 10         public static Expression And(this Expression thisFilter, Expression otherFilter)
 11         {
 12             return Expression.AndAlso(thisFilter, otherFilter);
 13         }
 14         /// <summary>
 15         /// 相當於||操作
 16         /// ——just0ne
 17         /// </summary>
 18         /// <param name="thisFilter">已生成的過濾條件</param>
 19         /// <param name="otherFilter">未生成的過濾條件</param>
 20         /// <returns>新的過濾</returns>
 21         public static Expression Or(this Expression thisFilter, Expression otherFilter)
 22         {
 23             return Expression.OrElse(thisFilter, otherFilter);
 24         }
 25         /// <summary>
 26         /// 相當於==操作
 27         /// ——just0ne
 28         /// </summary>
 29         /// <param name="thisParameterExpression">查詢對象</param>
 30         /// <param name="propertieName">屬性名稱</param>
 31         /// <param name="propertieValue">屬性值</param>
 32         /// <returns>新的過濾</returns>
 33         public static Expression GotoEqual(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 34         {
 35             return Expression.Equal(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue));
 36         }
 37         /// <summary>
 38         /// 相當於>=操作
 39         /// ——just0ne
 40         /// </summary>
 41         /// <param name="thisParameterExpression">查詢對象</param>
 42         /// <param name="propertieName">屬性名稱</param>
 43         /// <param name="propertieValue">屬性值</param>
 44         /// <returns>新的過濾</returns>
 45         public static Expression GotoGreaterThanOrEqual<T>(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 46         {
 47             //大於或等於
 48             return Expression.GreaterThanOrEqual(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(T)));
 49         }
 50         /// <summary>
 51         /// 相當於小於等於操作
 52         /// ——just0ne
 53         /// </summary>
 54         /// <param name="thisParameterExpression">查詢對象</param>
 55         /// <param name="propertieName">屬性名稱</param>
 56         /// <param name="propertieValue">屬性值</param>
 57         /// <returns>新的過濾</returns>
 58         public static Expression GotoLessThanOrEqual<T>(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 59         {
 60             //小於或等於
 61             return Expression.LessThanOrEqual(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(T)));
 62         }
 63         /// <summary>
 64         /// 相當於>操作
 65         /// ——just0ne
 66         /// </summary>
 67         /// <param name="thisParameterExpression">查詢對象</param>
 68         /// <param name="propertieName">屬性名稱</param>
 69         /// <param name="propertieValue">屬性值</param>
 70         /// <returns>新的過濾</returns>
 71         public static Expression GotoGreaterThan<T>(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 72         {
 73             //大於
 74             return Expression.GreaterThan(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(T)));
 75         }
 76         /// <summary>
 77         /// 相當於小於操作
 78         /// ——just0ne
 79         /// </summary>
 80         /// <param name="thisParameterExpression">查詢對象</param>
 81         /// <param name="propertieName">屬性名稱</param>
 82         /// <param name="propertieValue">屬性值</param>
 83         /// <returns>新的過濾</returns>
 84         public static Expression GotoLessThan<T>(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 85         {
 86             //小於
 87             return Expression.LessThan(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(T)));
 88         }
 89         /// <summary>
 90         /// 相當於>=操作
 91         /// ——just0ne
 92         /// </summary>
 93         /// <param name="thisParameterExpression">查詢對象</param>
 94         /// <param name="propertieName">屬性名稱</param>
 95         /// <param name="propertieValue">屬性值</param>
 96         /// <returns>新的過濾</returns>
 97         public static Expression GotoGreaterThanOrEqualByDateTime(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
 98         {
 99             //大於或等於
100             return Expression.GreaterThanOrEqual(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(DateTime?)));
101         }
102         /// <summary>
103         /// 相當於小於或等於操作
104         /// ——just0ne
105         /// </summary>
106         /// <param name="thisParameterExpression">查詢對象</param>
107         /// <param name="propertieName">屬性名稱</param>
108         /// <param name="propertieValue">屬性值</param>
109         /// <returns>新的過濾</returns>
110         public static Expression GotoLessThanOrEqualByDateTime(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
111         {
112             //小於或等於
113             return Expression.LessThanOrEqual(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(DateTime?)));
114         }
115         /// <summary>
116         /// 相當於>操作
117         /// ——just0ne
118         /// </summary>
119         /// <param name="thisParameterExpression">查詢對象</param>
120         /// <param name="propertieName">屬性名稱</param>
121         /// <param name="propertieValue">屬性值</param>
122         /// <returns>新的過濾</returns>
123         public static Expression GotoGreaterThanByDateTime(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
124         {
125             //大於
126             return Expression.GreaterThan(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(DateTime?)));
127         }
128         /// <summary>
129         /// 相當於小於操作
130         /// —一just0ne
131         /// </summary>
132         /// <param name="thisParameterExpression">查詢對象</param>
133         /// <param name="propertieName">屬性名稱</param>
134         /// <param name="propertieValue">屬性值</param>
135         /// <returns>新的過濾</returns>
136         public static Expression GotoLessThanByDateTime(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
137         {
138             //小於
139             return Expression.LessThan(Expression.Property(thisParameterExpression, propertieName), Expression.Constant(propertieValue, typeof(DateTime?)));
140         }
141 
142         /// <summary>
143         /// 一一just0ne
144         /// 包含操作 相當餘 a=> arr.Contains(a.ID)
145         /// 如果arr中數據量過大則不適用linq
146         /// </summary>
147         /// <param name="thisParameterExpression">查詢對象</param>
148         /// <param name="propertieName">屬性名稱</param>
149         /// <param name="propertieValue">屬性值</param>
150         /// <returns>新的過濾</returns>
151         public static Expression ContainsOperations(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
152         {
153             MethodInfo method = null;
154             MemberExpression member = Expression.Property(thisParameterExpression, propertieName);
155             var containsMethods = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(m => m.Name == "Contains");
156             foreach (var m in containsMethods)
157             {
158                 if (m.GetParameters().Count() == 2)
159                 {
160                     method = m;
161                     break;
162                 }
163             }
164             method = method.MakeGenericMethod(member.Type);
165             var exprContains = Expression.Call(method, new Expression[] { Expression.Constant(propertieValue), member });
166             return exprContains;
167         }
168 
169         /// <summary>
170         /// 一一just0ne
171         /// 包含操作 相當於  a=>a.ID.Contains(key)
172         /// </summary>
173         /// <param name="thisParameterExpression">查詢對象</param>
174         /// <param name="propertieName">屬性名稱</param>
175         /// <param name="propertieValue">屬性值</param>
176         /// <returns>新的過濾</returns>
177         public static Expression Contains(this ParameterExpression thisParameterExpression, string propertieName, object propertieValue)
178         {
179             var propertyExp = Expression.Property(thisParameterExpression, propertieName);
180             MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
181             var someValue = Expression.Constant(propertieValue, typeof(string));
182             var containsMethodExp = Expression.Call(propertyExp, method, someValue);
183             return containsMethodExp;
184         }
185 
186     }

以上就是一些基本的拼接都有了接下來是如何進行使用 我們還是貼上代碼進行說明

  class Program
    {
        static void Main(string[] args)
        {
            string[] nameArr = new string[] { "just0ne", "kphui", "point" };
            var userDataList = GetUserDataList().AsQueryable();
            //初始化
            var parameterExpression = Expression.Parameter(typeof(UserData));
            var filter = (Expression)Expression.Constant(true);
            //尋找年歲大於10
            filter = filter.And(parameterExpression.GotoGreaterThan<int>("Age", 10));
            string key = Console.ReadLine();
            if (!String.IsNullOrEmpty(key))
            {
                var keyFilter = (Expression)Expression.Constant(false);
                keyFilter = keyFilter.Or(parameterExpression.Contains("Name", key));
                keyFilter = keyFilter.Or(parameterExpression.Contains("Phone", key));
                filter = filter.And(keyFilter);
            }
            filter = filter.And(parameterExpression.ContainsOperations("Name", nameArr));
            var lamadaFilter = Expression.Lambda<Func<UserData, bool>>(filter, parameterExpression);
            var userDatas = userDataList.Where(lamadaFilter).ToList();
            Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(userDatas));
        }

        public static List<UserData> GetUserDataList()
        {
            return new List<UserData>()
            {
                new UserData(){ Age=18, Id=1, Name="just0ne", Phone="13856****26" },
                new UserData(){ Age=22, Id=2, Name="point", Phone="17521****52" },
                new UserData(){ Age=21, Id=3, Name="geekdog", Phone="15562****36" },
                new UserData(){ Age=14, Id=4, Name="kphui" , Phone="13577****26"},
                new UserData(){ Age=13, Id=5, Name="lg" , Phone="13456****26"},
                new UserData(){ Age=16, Id=6, Name="ming", Phone="13356****26" },
                new UserData(){ Age=18, Id=7, Name="tencent", Phone="13256****26" },
                new UserData(){ Age=10, Id=8, Name="justin" , Phone="13156****26"},
                new UserData(){ Age=31, Id=9, Name="hujw", Phone="13823****26" },
                new UserData(){ Age=27, Id=10, Name="lqm" , Phone="13876****26"},
                new UserData(){ Age=26, Id=11, Name="jiujiu" , Phone="13846****26"},
            };
        }
    }

    public class UserData
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public string Phone { get; set; }

        public string Email { get; set; }

        public int Age { get; set; }
    }

 

我們運行程式會輸出如下的內容:

以上只是針對如何使用表達式樹做個例子 如有不同的可以留言哦!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • centos7上部署dubbo管理控制台dubbo admin 1 準備工作 伺服器:系統centos7, 記憶體4G, 存儲60G, ip 192.168.159.128 軟體環境: 安裝有jdk1.8, 具體安裝方式參見《centos7上安裝jdk1.8》博文; 安裝並啟動zookeeper,具體 ...
  • 儘可能讓一切變得簡單,用最簡單的方式完成工作 能用最少的概念,最精簡易懂的概念模型來抽象系統,多一個概念就多一份別人瞭解系統以及維護系統的複雜度,別人也會質疑多一個概念的意義所在,自己如果沒想清楚就容易被diss。 特別是在類的設計中,會發現其實很多時候用一個類就可以表達要乾的單一職責了,每個類職責 ...
  • 1.什麼是spring boot 答案:springboot是用來簡化spring應用的初始搭建和開發過程,使用特定的配置文件來配置,例如application.properties,簡化來maven配置,使項目從繁到簡。 2.springboot與spring的區別。 答案:1)Java在集成sp ...
  • 1.SpringMVC: SpringMVC是基於java的實現MVC設計模式的請求驅動類型的輕量級的web框架,通常把model,view,controller將web層進行職責解耦, 把複雜的web應用分層邏輯清晰的幾部分,簡化開發,減少錯誤,方便組內人員之間的配合。 SpringMVC框架和其 ...
  • 2019-09-19-22:11:33 今天是自學Python的第九天 學的內容是有關文件操作的,如:r、w、a、rb、wb、ab、r+、w+、a+等 有大牛幫我看一下我的代碼第一個有沒有什麼弊端嗎?我感覺好像沒有,但是看視頻時,說不建議這樣做 ...
  • 前言 上一篇文章開始了我們的springboot序篇,我們配置了mysql資料庫,但是我們sql語句直接寫在controller中並且使用的是jdbcTemplate。項目中肯定不會這樣使用,上篇文章也說了,會結合mybatis 或者JPA 使用。我們這篇文章就來結合 mybatis 來使用吧,至於 ...
  • 1.消息隊列介紹 消息隊列本質上來說是一個符合先進先出原則的單向隊列:一方發送消息並存入消息隊列尾部(生產者投遞消息),一方從消息隊列的頭部取出消息(消費者消費消息)。但對於一個成熟可靠的消息隊列來說,所需要解決的主要問題還包括:高效可靠的消息投遞、存儲;能承受高併發的流量衝擊,可通過集群部署來解決 ...
  • 如果已經看過本章節:目錄傳送門:這是目錄鴨~ 上節內容寫了Actor管理器,那麼這一節讓我們先創建一個角色。(此章節開始加速...) 1.製作角色展示AssetBundle: 提取農藥某個展示模型(Show)資源(這步具體去百度),然後再把模型製作成預製體,AssetBundle命名規則按照農藥的( ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...