Linq-Expression表达式树

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Diagnostics;

namespace TestLinq.linqToSql
{
    /// <summary>
    /// 表达式树
    /// </summary>
    public static class ExpressionExtension
    {
        public static void Test1()
        {
            Func<int, bool> deleg = i => i < 5;
            Console.WriteLine("deleg(4)={0}", deleg(4));
            System.Linq.Expressions.Expression<Func<int, bool>> expr = i => i < 5;
            //将表达式树描述的lambda表达式编译为可执行代码,并生成表示该lambda表达式的委托
            Func<int, bool> deleg2 = expr.Compile();
            Console.WriteLine("deleg2(4)={0}", deleg2(4));
        }

        public static void Test()
        {
            #region and 连接linq
            Stopwatch s = new Stopwatch();
            string[] strArray = new[] {"1", "134562", "321", "123", "456", "36", "dfd"};
            s.Start();
            Expression<Func<string, bool>> testexpr = True<string>();
            testexpr = testexpr.And(x => x.Contains("1"));
            testexpr = testexpr.And(x => x.Contains("2"));
            var list = strArray.AsQueryable().Where(testexpr);
            Console.WriteLine("And测试输出:");
            foreach (var str in list)
            {
                Console.WriteLine(str);
            }
            s.Stop();
            Console.WriteLine(s.Elapsed);


            #endregion

            s.Restart();
            #region or连接linq
            Expression<Func<string, bool>> orexpr = False<string>();
            orexpr = orexpr.Or(x => x.Contains("1"));
            orexpr = orexpr.Or(x => x.Contains("3"));
            var orlist = strArray.AsQueryable().Where(orexpr);
            Console.WriteLine("Or测试输出:");
            foreach (var str in orlist)
            {
                Console.WriteLine(str);
            }
            #endregion
            s.Stop();
            Console.WriteLine(s.Elapsed);
            //#region OrderBy
            //Expression<Func<string, bool>> orderbyexpr = True<string>();
            //orderbyexpr = testexpr.And(x => x.Contains("1"));
            //orderbyexpr = testexpr.Or(x => x.Contains("2"));
            //var orderlist = strArray.AsQueryable().Where(orderbyexpr).OrderBy("", true);
            //#endregion
        }

        public static void TestModel()
        {
            GuestSearch guestsearch = new GuestSearch();
            guestsearch.StartAge = 200;
            guestsearch.EndAge = 100000;
            guestsearch.Sex = true;
            guestsearch.Name = "3";
            List<GuestInfo> gestlist = new List<GuestInfo>();
            for (int i = 0; i < 1000000; i++)
            {
                GuestInfo info = new GuestInfo
                                {
                                    Name = "Name" + i,
                                    Age = i,
                                    Tel = "13872445357",
                                    Code = i.ToString(),
                                    AddTime=DateTime.Now
                                };
                if (i%2 == 0) info.Sex = true;
                gestlist.Add(info);
            }
            #region And
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Expression<Func<GuestInfo, bool>> sexpr1 = True<GuestInfo>();
            if (!string.IsNullOrEmpty(guestsearch.Name))
            {
                sexpr1=sexpr1.And(x => x.Name.Contains(guestsearch.Name));
            }
           sexpr1= sexpr1.And(x => x.Age > guestsearch.StartAge && x.Age < guestsearch.EndAge);
           sexpr1= sexpr1.And(x => x.Sex);
           var test1= gestlist.AsQueryable().Where(sexpr1);
            Console.WriteLine(test1.Count());
            sw.Stop();
            Console.WriteLine("And运行时间:"+sw.Elapsed);
            #endregion

            sw.Restart();
            var test2 = gestlist.Where(o => o.GetSearch(guestsearch));
           Console.WriteLine(test2.Count());
            sw.Stop();
            Console.WriteLine("where运行时间:" + sw.Elapsed);
        }


        public static bool GetSearch(this GuestInfo guestInfo, GuestSearch guestsearch)
        {
            if (!string.IsNullOrEmpty(guestsearch.Name))
            {
                if (!guestInfo.Name.Contains(guestsearch.Name)) return false;
            }
            if (guestInfo.Age <= guestsearch.StartAge || guestInfo.Age >= guestsearch.EndAge) return false;
            if (!guestInfo.Sex) return false;
            return true;
        }



        /// <summary>
        /// 构造器
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static Expression<Func<T, bool>> True<T>() { return f =>true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }
        /// <summary>
        /// 连接
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="andleft"></param>
        /// <param name="andright"></param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> andleft,
                                                       Expression<Func<T, bool>> andright)
        {
            //添加参数
            var candidateExpr = Expression.Parameter(typeof(T));
            var parameterReplacer = new ParameterReplacer(candidateExpr);
            var left = parameterReplacer.Replace(andleft.Body);
            var right = parameterReplacer.Replace(andright.Body);
            var body = Expression.And(left, right);
            return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
 
        }

        /// <summary>
        /// or连接
        /// </summary>
        /// <typeparam name="T">模型</typeparam>
        /// <param name="andleft">表达式</param>
        /// <param name="andright">追加的lamb表达式</param>
        /// <returns></returns>
        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> andleft, Expression<Func<T, bool>> andright)
        {
            var candidateExpr = Expression.Parameter(typeof(T));
            var parameterReplacer = new ParameterReplacer(candidateExpr);
            var left = parameterReplacer.Replace(andleft.Body);
            var right = parameterReplacer.Replace(andright.Body);
            var body = Expression.Or(left, right);
            return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
        }

        /// <summary>
        /// 排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="propertyName"></param>
        /// <param name="ascending"></param>
        /// <returns></returns>
        public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, bool ascending) where T : class
        {
            var type = typeof(T);
            var property = type.GetProperty(propertyName);
            if (property == null)
                throw new ArgumentException(propertyName + "在" + type.Name + "的成员里不存在", propertyName);

            var param = Expression.Parameter(type, "p");
            Expression propertyAccessExpression = Expression.MakeMemberAccess(param, property);
            var orderByExpression = Expression.Lambda(propertyAccessExpression, param);

            var methodName = ascending ? "OrderBy" : "OrderByDescending";
            var resultExp = Expression.Call(typeof(Queryable), methodName, new Type[] { type, property.PropertyType },
                                            source.Expression, Expression.Quote(orderByExpression));
            return source.Provider.CreateQuery<T>(resultExp);
        }

        /// <summary>
        /// 统一ParameterExpression
        /// </summary>
        internal class ParameterReplacer : ExpressionVisitor
        {
            public ParameterReplacer(ParameterExpression paramExpr)
            {
                this.ParameterExpression = paramExpr;
            }
            public ParameterExpression ParameterExpression { get; private set; }
            public Expression Replace(Expression expr)
            {
                return this.Visit(expr);
            }
            protected override Expression VisitParameter(ParameterExpression p)
            {
                return this.ParameterExpression;
            }
        }
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值