[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.結果:
留言
張貼留言