[C#] Linq Expression Or,And clause
如果今天有多個表達式,想要用「or」或者「and」將兩個表達式的條件串起來,該如何實作呢?
在爬了一些文後,我發現了這個寫法是最可行的。
實作:
1.新增一個 Expression 擴充方法
public static class ExpressionExtenssion { public static Expression< Func < T , bool > > ExpressionAnd< T >(this Expression< Func < T , bool > > expr1, Expression< Func < T , bool > > expr2) { var secondBody = expr2.Body.Replace( expr2.Parameters[0], expr1.Parameters[0]); return Expression.Lambda> (Expression.AndAlso(expr1.Body, secondBody), expr1.Parameters); } public static Expression< Func < T , bool > > ExpressionOr< T >(this Expression< Func < T , bool > > expr1, Expression< Func < T, bool > > expr2) { var secondBody = expr2.Body.Replace( expr2.Parameters[0], expr1.Parameters[0]); return Expression.Lambda< Func < T , bool > > (Expression.OrElse(expr1.Body, secondBody), expr1.Parameters); } public static Expression Replace(this Expression expression, Expression searchEx, Expression replaceEx) { return new ReplaceVisitor(searchEx, replaceEx).Visit(expression); } internal class ReplaceVisitor : ExpressionVisitor { private readonly Expression from, to; public ReplaceVisitor(Expression from, Expression to) { this.from = from; this.to = to; } public override Expression Visit(Expression node) { return node == from ? to : base.Visit(node); } } }
2.範例:
public void Main() { //測試資料 var test = new List() { new TestModel() { Age=5, Name="Baby" } }; //條件一 Expression< Func < TestModel , bool > > leftexp = x => x.Name == "Baby"; //條件二 Expression< Func < TestModel , bool > > rightexp = x => x.Age == 3; //and後的表達式 var andExp = leftexp.ExpressionAnd(rightexp).Compile(); var result = test.Any(andExp); Console.WriteLine($"And:{result}"); //or後的表達式 var orExp = leftexp.ExpressionOr(rightexp).Compile(); result = test.Any(orExp); Console.WriteLine($"or:{result}"); Console.ReadLine(); } /// /// 測試模型 /// public class TestModel { public string Name { get; set; } public int Age { get; set; } }
3.結果:
留言
張貼留言