[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.結果:





留言

這個網誌中的熱門文章

[Visual Studio]位於網際網路或是限制區域上 或是檔案上標有 web 字樣 所以無法處理該檔案。若希望處理這些檔案 請移除 web 字樣。

[IIS] IIS執行時,發生拒絕存取路徑 問題

[windows] xcopy 備份至 「網路磁碟機」