一、原理分析
上篇裡面我們說了動態Lambda的使用必要性以及使用場景,但是感覺用在專案裡面還不太方便,最難用的就是需要傳遞屬性名稱的字串,感覺這有點太lower了。然後就是那個列舉的使用著實感覺沒啥必要,我們只需要將Contains、Equal、LessThan、GreaterThan等方法分別封裝一個獨立的方法即可。好了,多說容易讓人頭暈,直接上程式碼吧。
二、程式碼示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
public class LamadaExtentionwhere Dto:new () { private List m_lstExpression = null; private ParameterExpression m_Parameter = null; public LamadaExtention() { m_lstExpression = new List(); m_Parameter = Expression.Parameter(typeof(Dto), "x"); } //只讀屬性,返回生成的Lamada public Expressionbool>> Lamada { get { return GetLambda(); } } /// /// 字串Contains篩選 /// /// /// public void Contains(Expressionstring>> expProperty, object strValue) { Expression expRes = Expression.Call(expProperty.Body, typeof(string).GetMethod("Contains"), Expression.Constant(strValue)); m_lstExpression.Add(expRes); } /// /// 等於 /// /// /// public void Equal(Expressionobject>> expProperty, object strValue) { var member = GetMemberExpression(expProperty); Expression expRes = Expression.Equal(member, Expression.Constant(strValue, member.Type)); m_lstExpression.Add(expRes); } /// /// 小於 /// /// /// public void LessThan(Expressionobject>> expProperty, object strValue) { var member = GetMemberExpression(expProperty); Expression expRes = Expression.LessThan(member, Expression.Constant( strValue, member.Type)); m_lstExpression.Add(expRes); } /// /// 小於等於 /// /// /// public void LessThanOrEqual(Expressionobject>> expProperty, object strValue) { var member = GetMemberExpression(expProperty); Expression expRes = Expression.LessThanOrEqual(member, Expression.Constant(strValue, member.Type)); m_lstExpression.Add(expRes); } /// /// 大於 /// /// /// public void GreaterThan(Expressionobject>> expProperty, object strValue) { var member = GetMemberExpression(expProperty); Expression expRes = Expression.GreaterThan(member, Expression.Constant(strValue, member.Type)); m_lstExpression.Add(expRes); } /// /// 大於等於 /// /// /// public void GreaterThanOrEqual(Expressionobject>> expProperty, object strValue) { var member = GetMemberExpression(expProperty); Expression expRes = Expression.GreaterThanOrEqual(member, Expression.Constant(strValue, member.Type)); m_lstExpression.Add(expRes); }private Expressionbool>> GetLambda() { Expression whereExpr = null; foreach (var expr in this.m_lstExpression) { if (whereExpr == null) whereExpr = expr; else whereExpr = Expression.And(whereExpr, expr); } if (whereExpr == null) return null; return Expression.Lambda>(whereExpr, m_Parameter); } //得到MemberExpression private MemberExpression GetMemberExpression(Expressionobject>> exp) { var arrSplit = exp.Body.ToString().Split("(.)".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); var strProperty = arrSplit[arrSplit.Length - 1]; MemberExpression member = Expression.PropertyOrField(m_Parameter, strProperty); return member; } } |
可以看出,對於常用的操作我們封裝了Contains、Equal、LessThan、LessThanOrEqual、GreaterThan、GreaterThanOrEqual六個方法,除了Contains方法的引數直接使用了Expression>型別以為,其他都用的Expression>。因為Contains方法只可能是string型別的變數操作,而其他操作可能涉及其他型別,就是為了傳這個object型別,有個問題博主除錯了很久,由於傳過來的是object,這個要得到屬性的真是型別貌似不那麼容易了,找了很久都沒找到。最後只能通過GetMemberExpression這個方法來得到MemberExpression。
還是來看看如何使用:
1 2 3 4 5 6 7 |
public object GetUsers(int limit, int offset, string username, string fullname) { var oLamadaExtention = new LamadaExtention(); oLamadaExtention.Equal(x => x.USER_NAME, username); oLamadaExtention.LessThan(x => x.MODIFYTIME, DateTime.Now); var lstRes = UserManager.Find(oLamadaExtention.lamada).ToList(); } |
最大的方便就是我們想要篩選的欄位可以通過lamada點出來了,再看看之前的那種用法
1 |
oLamadaExtention.GetExpression("USER_NAME", username, ExpressionType.Contains); |
有沒有瞬間高大上。USER_NAME直接點出來,比敲字串要爽吧。感謝神奇的Lamada,感謝全能的C#。