運算式樹狀架構動態拼接lambda

來源:互聯網
上載者:User

標籤:

前言

  最近在最佳化同事寫的代碼(我們的架構用的是dapperLambda),其中有一個這樣很普通的情境——介面上提供了一些查詢條件框供使用者來進行過濾資料。由於dapperLambda按條件查詢時是傳入運算式樹狀架構的參數,這樣比如其中查詢條件有一個是審核狀態,另外五個是模糊查詢,那這查詢時的運算式樹狀架構參數就要寫兩次,這樣使得代碼看起來有很多是重複的,而且如果查詢條件多的情況下,在寫那運算式樹狀架構參數時也容易漏寫或錯寫。所以我在想如果可以動態拼接這運算式樹狀架構,那這代碼就要精簡很多了。

 本文

  也許我的上面文字描述讓你不明覺裡,那下面我就配以簡單的代碼來再說明一下這個問題:

1 Expression<Func<SysUser, bool>> exp1 = s => s.UserName.Contains("1") && s.Age > 10;2 Expression<Func<SysUser, bool>> exp2 = s => s.UserName.Contains("1") && s.Age > 10 && s.IsEnable == 1;3 using (var context = new DbContext().ConnectionString(connString))4 {5     var result1 = context.Select<SysUser>(exp1).QueryMany();6     var result2 = context.Select<SysUser>(exp2).QueryMany();7 }

  上面代碼兩次查詢,第一次查詢結果result1的結果是使用者名稱中包含1而且年齡大於10,而結果result2中就是在查詢結果result1的條件上再加上帳號生效這一條件。所以我們看到exp1和exp2的運算式樹狀架構絕大部分是相同的,在這個樣本裡看著這點重複代碼似乎還是可以接受的,但是在真實環境下,重複的代碼就不止這一點點了。因為exp2和exp1相比,exp2隻是在exp1之上多加了一個條件,那我們有沒有方法可以在exp1的基礎上再加一個條件賦值給exp2呢?答案當然是可以的。

  運算式擴充類:

 1 public static class ExpressionExt 2 { 3     public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) 4     {           5         return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(expr1.Body, expr2.Body), expr1.Parameters); 6     } 7     public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,Expression<Func<T, bool>> expr2) 8     { 9         return Expression.Lambda<Func<T, bool>>(Expression.OrElse(expr1.Body, expr2.Body), expr1.Parameters);10     }11 }

  上面這代碼是我們這文章的核心,我在這裡順便解釋一下這個And擴充方法它是怎麼做的,它這裡先是使用Expression類中的靜態方法AndAlso把expr1和expr2的主體拼接在一起,如果AndAlso方法返回的是BinaryExpression類型的結果,而dapperLambda的條件參數需要的是Lambda運算式樹狀架構,所以這裡我們需要通過Expression.Lambda方法來構造一個委託類型來建立一個Lambda表達樹。

  那現在我們通過上面的擴充方法,再來最佳化一下我們最初舉的例子看下:

1 Expression<Func<SysUser, bool>> exp1 = s => s.UserName.Contains("1") && s.Age > 0;2 Expression<Func<SysUser, bool>> exp2 =exp1.And( s => s.IsEnable == 1);3 using (var context = new DbContext().ConnectionString(connString))4 {5     var result1 = context.Select<SysUser>(exp1).QueryMany();6     var result2 = context.Select<SysUser>(exp2).QueryMany();7 }
結束語

 雖然這個擴充方法就只有幾行代碼,但是如果少了這幾行代碼,在我們的代碼裡可能就要上了幾十行、幾百行代碼了。有時解決問題的關鍵就是那麼一個不起眼的東西,但就是這麼一個不起眼的東西就能幫我們解決一些大問題。

  說到這,讓我想起了一句話——每多學一點知識,就少寫一行代碼。

運算式樹狀架構動態拼接lambda

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.