public static void MapperTest()
        {
            People people = new People()
            {
                Id   = 11,
                Name = "Eleven",
                Age  = 31
            };

            long common     = 0;
            long generic    = 0;
            long cache      = 0;
            long reflection = 0;
            long serialize  = 0;

            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                for (int i = 0; i < 1000000; i++)
                {
                    PeopleCopy peopleCopy = new PeopleCopy()
                    {
                        Id   = people.Id,
                        Name = people.Name,
                        Age  = people.Age
                    };
                }
                watch.Stop();
                common = watch.ElapsedMilliseconds;
            }
            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                for (int i = 0; i < 1000000; i++)
                {
                    PeopleCopy peopleCopy = ReflectionMapper.Trans <People, PeopleCopy>(people);
                }
                watch.Stop();
                reflection = watch.ElapsedMilliseconds;
            }
            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                for (int i = 0; i < 1000000; i++)
                {
                    PeopleCopy peopleCopy = SerializeMapper.Trans <People, PeopleCopy>(people);
                }
                watch.Stop();
                serialize = watch.ElapsedMilliseconds;
            }
            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                for (int i = 0; i < 1000000; i++)
                {
                    PeopleCopy peopleCopy = ExpressionMapper.Trans <People, PeopleCopy>(people);
                }
                watch.Stop();
                cache = watch.ElapsedMilliseconds;
            }
            {
                Stopwatch watch = new Stopwatch();
                watch.Start();
                for (int i = 0; i < 1000000; i++)
                {
                    PeopleCopy peopleCopy = ExpressionGenericMapper <People, PeopleCopy> .Trans(people);
                }
                watch.Stop();
                generic = watch.ElapsedMilliseconds;
            }

            Console.WriteLine($"common = { common} ms");
            Console.WriteLine($"reflection = { reflection} ms");
            Console.WriteLine($"serialize = { serialize} ms");
            Console.WriteLine($"cache = { cache} ms");
            Console.WriteLine($"generic = { generic} ms");
        }
 public static void MapperTest()
 {
     {
         //People people = new People()
         //{
         //    Id = 11,
         //    Name = "Richard",
         //    Age = 31
         //};
         //PeopleCopy peopleCopy = new PeopleCopy()//硬编码 //硬编码性能好,但是通用型差
         //{
         //    Id = people.Id,
         //    Name = people.Name,
         //    Age = people.Age
         //};
         ////如果说有其他别的类型需要转换,那么不是为所有的类型都需要写这样代码?
         //PeopleCopy peopleCopy1 = ReflectionMapper.Trans<People, PeopleCopy>(people);//反射+泛型方法
         //PeopleCopy peopleCopy2 = SerializeMapper.Trans<People, PeopleCopy>(people);
         ////Func<People, PeopleCopy> exp1 = p =>
         ////{
         ////    return new PeopleCopy()
         ////    {
         ////        Id = p.Id,
         ////        Name = p.Name,
         ////        Age = p.Age
         ////    };
         ////};
         ////泛型方法+表达式目录 = 既可以通用,效率高
         //PeopleCopy peopleCopy3 = ExpressionMapper.Trans<People, PeopleCopy>(people);
         //PeopleCopy peopleCopy4 = ExpressionGenericMapper<People, PeopleCopy>.Trans(people);
     }
     {
         Console.WriteLine("****************************性能测试结果***************************");
         People people = new People()
         {
             Id   = 11,
             Name = "Richard",
             Age  = 31
         };
         long common     = 0;
         long generic    = 0;
         long cache      = 0;
         long reflection = 0;
         long serialize  = 0;
         {
             Stopwatch watch = new Stopwatch();
             watch.Start();
             for (int i = 0; i < 100_000; i++)
             {
                 PeopleCopy peopleCopy = new PeopleCopy()
                 {
                     Id   = people.Id,
                     Name = people.Name,
                     Age  = people.Age
                 };
             }
             watch.Stop();
             common = watch.ElapsedMilliseconds;
         }
         {
             Stopwatch watch = new Stopwatch();
             watch.Start();
             for (int i = 0; i < 100_000; i++)
             {
                 PeopleCopy peopleCopy = ReflectionMapper.Trans <People, PeopleCopy>(people);
             }
             watch.Stop();
             reflection = watch.ElapsedMilliseconds;
         }
         {
             Stopwatch watch = new Stopwatch();
             watch.Start();
             for (int i = 0; i < 100_000; i++)
             {
                 PeopleCopy peopleCopy = SerializeMapper.Trans <People, PeopleCopy>(people);
             }
             watch.Stop();
             serialize = watch.ElapsedMilliseconds;
         }
         {
             Stopwatch watch = new Stopwatch();
             watch.Start();
             for (int i = 0; i < 100_000; i++)
             {
                 PeopleCopy peopleCopy = ExpressionMapper.Trans <People, PeopleCopy>(people);
             }
             watch.Stop();
             cache = watch.ElapsedMilliseconds;
         }
         {
             Stopwatch watch = new Stopwatch();
             watch.Start();
             for (int i = 0; i < 100_000; i++)
             {
                 PeopleCopy peopleCopy = ExpressionGenericMapper <People, PeopleCopy> .Trans(people);
             }
             watch.Stop();
             generic = watch.ElapsedMilliseconds;
         }
         Console.WriteLine($"common = { common} ms");
         Console.WriteLine($"reflection = { reflection} ms");
         Console.WriteLine($"serialize = { serialize} ms");
         Console.WriteLine($"cache = { cache} ms");
         Console.WriteLine($"generic = { generic} ms");
     }
     //通过拼接表达式目录树+ 泛型缓存性能最高!
     //硬编码性能最高,为了通用,动态生成硬编码==最完美
 }
        public static void Show()
        {
            {
                Func <int, int, int> func = (m, n) => m * n + 2;              // new Func<int, int, int>((m, n) => m * n + 2);
                Expression <Func <int, int, int> > exp = (m, n) => m * n + 2; //lambda表达式声明表达式目录树
                                                                              //Expression<Func<int, int, int>> exp1 = (m, n) =>//只能一行 不能有大括号
                                                                              //    {
                                                                              //        return m * n + 2;
                                                                              //    };
                                                                              //Queryable    //a=>a.Id>3

                //表达式目录树:语法树,或者说是一种数据结构;可以被我们解析
                int iResult1 = func.Invoke(12, 23);
                int iResult2 = exp.Compile().Invoke(12, 23);//可以转换过去
            }
            {
                Expression <Func <int, int, int> > exp   = (m, n) => m * n + 2;
                ParameterExpression parameterExpression  = Expression.Parameter(typeof(int), "m");
                ParameterExpression parameterExpression2 = Expression.Parameter(typeof(int), "n");
                var multiply = Expression.Multiply(parameterExpression, parameterExpression2);
                var constant = Expression.Constant(2, typeof(int));
                var add      = Expression.Add(multiply, constant);

                Expression <Func <int, int, int> > expression =
                    Expression.Lambda <Func <int, int, int> >(
                        add,
                        new ParameterExpression[]
                {
                    parameterExpression,
                    parameterExpression2
                });

                int iResult1 = exp.Compile().Invoke(11, 12);
                int iResult2 = expression.Compile().Invoke(11, 12);
            }

            //自己拼装表达式目录树
            {
                //常量
                ConstantExpression  conLeft       = Expression.Constant(345);
                ConstantExpression  conRight      = Expression.Constant(456);
                BinaryExpression    binary        = Expression.Add(conLeft, conRight);        //345+456
                Expression <Action> actExpression = Expression.Lambda <Action>(binary, null); //()=>345+456
                //只能执行表示Lambda表达式的表达式目录树,即LambdaExpression或者Expression<TDelegate>类型。如果表达式目录树不是表示Lambda表达式,需要调用Lambda方法创建一个新的表达式
                actExpression.Compile()();                                                    //()=>345+456
            }

            {
                ParameterExpression paraLeft   = Expression.Parameter(typeof(int), "a");   //左边
                ParameterExpression paraRight  = Expression.Parameter(typeof(int), "b");   //右边
                BinaryExpression    binaryLeft = Expression.Multiply(paraLeft, paraRight); //a*b
                ConstantExpression  conRight   = Expression.Constant(2, typeof(int));      //右边常量
                BinaryExpression    binaryBody = Expression.Add(binaryLeft, conRight);     //a*b+2

                Expression <Func <int, int, int> > lambda =
                    Expression.Lambda <Func <int, int, int> >(binaryBody, paraLeft, paraRight);
                Func <int, int, int> func = lambda.Compile();//Expression Compile成委托
                int result = func(3, 4);
            }
            {
                Expression <Func <People, bool> > lambda = x => x.Id.ToString().Equals("5");
                ParameterExpression parameterExpression  = Expression.Parameter(typeof(People), "x");
                var field        = Expression.Field(parameterExpression, typeof(People).GetField("Id"));
                var toString     = typeof(People).GetMethod("ToString");
                var toStringCall = Expression.Call(field, toString, new Expression[0]);
                var equals       = typeof(People).GetMethod("Equals");
                var constant     = Expression.Constant("5", typeof(string));
                var equalsCall   = Expression.Call(toStringCall, equals, new Expression[] { constant });
                Expression <Func <People, bool> > expression =
                    Expression.Lambda <Func <People, bool> >(equalsCall, new ParameterExpression[]
                {
                    parameterExpression
                });

                expression.Compile().Invoke(new People()
                {
                    Id   = 11,
                    Name = "Eleven",
                    Age  = 31
                });
            }

            {
                ParameterExpression  parameterExpression = Expression.Parameter(typeof(People), "x");
                Expression           field              = Expression.Field(parameterExpression, typeof(People).GetField("Id"));
                MethodCallExpression toString           = Expression.Call(field, typeof(People).GetMethod("ToString"), new Expression[0]);
                ConstantExpression   constantExpression = Expression.Constant("5", typeof(string));

                MethodCallExpression equals = Expression.Call(toString, typeof(People).GetMethod("Equals"), new Expression[] { constantExpression });
                Expression <Func <People, bool> > lambda = Expression.Lambda <Func <People, bool> >(equals, new ParameterExpression[]
                {
                    parameterExpression
                });
                bool bResult = lambda.Compile()(new People()
                {
                    Id   = 11,
                    Name = "Eleven",
                    Age  = 31
                });
            }
            {
                //以前根据用户输入拼装条件
                string sql  = "SELECT * FROM USER WHERE 1=1";
                string name = "Eleven";//用户选择条件
                if (string.IsNullOrWhiteSpace(name))
                {
                    sql += $" and name like '%{name}%'";//应该参数化
                }


                //现在entityx framework查询的时候,需要一个表达式目录树
                IQueryable <int> list = null;
                //都不过滤 1
                if (true)//只过滤A 2
                {
                    //list=list.Where();
                    Expression <Func <People, bool> > exp1 = x => x.Id > 1;
                }
                if (true)//只过滤B 3
                {
                    //list=list.Where();
                    Expression <Func <People, bool> > exp2 = x => x.Age > 10;
                }

                //都过滤 4
                Expression <Func <People, bool> > exp3 = x => x.Id > 1 && x.Age > 10;
                //2个条件  4种可能  排列组合
                //3个条件  2的3次方

                //list.Where()

                //拼装表达式目录树,交给下端用
                //Expression<Func<People, bool>> lambda = x => x.Age > 5;
                ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x");
                Expression          propertyExpression  = Expression.Property(parameterExpression, typeof(People).GetProperty("Age"));
                //Expression property = Expression.Field(parameterExpression, typeof(People).GetField("Id"));
                ConstantExpression constantExpression    = Expression.Constant(5, typeof(int));
                BinaryExpression   binary                = Expression.GreaterThan(propertyExpression, constantExpression);//添加方法的
                Expression <Func <People, bool> > lambda = Expression.Lambda <Func <People, bool> >(binary, new ParameterExpression[]
                {
                    parameterExpression
                });
                bool bResult = lambda.Compile()(new People()
                {
                    Id   = 11,
                    Name = "Eleven",
                    Age  = 31
                });
            }

            {
                People people = new People()
                {
                    Id   = 11,
                    Name = "Eleven",
                    Age  = 31
                };
                PeopleCopy peopleCopy = new PeopleCopy()
                {
                    Id   = people.Id,
                    Name = people.Name,
                    Age  = people.Age
                };
                //硬编码 是不是写死了  只能为这两个类型服务   性能是最好的

                {
                    //反射 不同类型都能实现
                    var result = ReflectionMapper.Trans <People, PeopleCopy>(people);
                }
                {
                    //序列化器  不同类型都能实现
                    var result = SerializeMapper.Trans <People, PeopleCopy>(people);
                }
                {
                    //1 通用   2 性能要高
                    //能不能动态的生成硬编码,缓存起来
                    var result = ExpressionMapper.Trans <People, PeopleCopy>(people);
                }
                {
                    var result = ExpressionMapper.Trans <People, PeopleCopy>(people);
                }
                {
                    var result = ExpressionGenericMapper <People, PeopleCopy> .Trans(people);
                }
                {
                    var result = ExpressionGenericMapper <People, PeopleCopy> .Trans(people);
                }
                //总结表达式目录树动态生成的用途了:
                //可以用来替代反射,因为反射可以通用,但是性能不够
                //生成硬编码,可以提升性能
                //automapper基于emit  动态生成硬编码

                //Expression<Func<People, PeopleCopy>> lambda = p =>
                //        new PeopleCopy()
                //        {
                //            Id = p.Id,
                //            Name = p.Name,
                //            Age = p.Age
                //        };
                //lambda.Compile()(people);

                ParameterExpression  parameterExpression = Expression.Parameter(typeof(People), "p");
                List <MemberBinding> memberBindingList   = new List <MemberBinding>();
                foreach (var item in typeof(PeopleCopy).GetProperties())
                {
                    MemberExpression property      = Expression.Property(parameterExpression, typeof(People).GetProperty(item.Name));
                    MemberBinding    memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }
                foreach (var item in typeof(PeopleCopy).GetFields())
                {
                    MemberExpression property      = Expression.Field(parameterExpression, typeof(People).GetField(item.Name));
                    MemberBinding    memberBinding = Expression.Bind(item, property);
                    memberBindingList.Add(memberBinding);
                }
                MemberInitExpression memberInitExpression      = Expression.MemberInit(Expression.New(typeof(PeopleCopy)), memberBindingList.ToArray());
                Expression <Func <People, PeopleCopy> > lambda = Expression.Lambda <Func <People, PeopleCopy> >(memberInitExpression, new ParameterExpression[]
                {
                    parameterExpression
                });
                Func <People, PeopleCopy> func = lambda.Compile();
                PeopleCopy copy = func(people);
            }
        }
Esempio n. 4
0
        public static void Show()
        {
            {
                Func <int, int, int> func = (m, n) => m * 2 + 2;              // lambda 只是一个方法

                Expression <Func <int, int, int> > exp = (m, n) => m * n + 2; //lambda 表达式声明 表达式目录树

                //Expression<Func<int, int, int>> exp1 = (m, n) => // 表达式目录树只能一行,不能有大括号
                //{
                //    return m * n + 2;
                //};


                // 表达式目录树: 语法树, 或者说一种数据结构;可以被我们解析。
                int iResult1 = func.Invoke(12, 23);
                int iResult2 = exp.Compile().Invoke(12, 23); // Compile 之后返回的是一个委托实例

                Console.WriteLine();
            }
            {
                //lambda 写法
                Expression <Func <int, int, int> > exp = (m, n) => m * n + 2;
                // 不用lambda的写法

                ParameterExpression parameterExpression  = Expression.Parameter(typeof(int), "m");
                ParameterExpression parameterExpression2 = Expression.Parameter(typeof(int), "n");

                BinaryExpression   multiply = Expression.Multiply(parameterExpression, parameterExpression2);
                ConstantExpression constant = Expression.Constant(2, typeof(int));
                BinaryExpression   add      = Expression.Add(multiply, constant);

                Expression <Func <int, int, int> > expression = Expression.Lambda <Func <int, int, int> >(
                    add,
                    new ParameterExpression[]
                {
                    parameterExpression,
                    parameterExpression2
                });
            }

            {
                ConstantExpression conLeft  = Expression.Constant(345);
                ConstantExpression conRight = Expression.Constant(234);

                BinaryExpression add = Expression.Add(conLeft, conRight);

                Expression <Action> actExpression = Expression.Lambda <Action>(add, null); // ()=>345 + 456;
                actExpression.Compile()();
            }
            {
                Expression <Func <People, bool> > lambda = x => x.Id.ToString().Equals("5");

                ParameterExpression parameterExpression = Expression.Parameter(typeof(People), "x");
                var field    = Expression.Field(parameterExpression, typeof(People).GetField("Id"));
                var toString = typeof(People).GetMethod("ToString");
                var equals   = typeof(People).GetMethod("Equals");

                var body = Expression.Call(
                    Expression.Call(
                        field,
                        toString,
                        new Expression[0]),
                    equals,
                    new Expression[]
                {
                    Expression.Constant("5", typeof(string))
                });

                Expression <Func <People, bool> > expression = Expression.Lambda <Func <People, bool> >(
                    body,
                    new ParameterExpression[]
                {
                    parameterExpression
                }

                    );

                var result = expression.Compile()(new People()
                {
                    Id = 5
                });

                Console.WriteLine(result);
            }

            {
                // 用处1
                {
                    string sql  = "Select * from user where 1=1";
                    string name = "ivan";

                    if (string.IsNullOrWhiteSpace(name))
                    {
                        sql += $" and name like '%{name}%'";
                    }
                }

                {
                    //现在entity framework查询的时候,都需要一个表达式目录树

                    IQueryable <int> list = null;

                    if (true) //过滤A
                    {
                        Expression <Func <People, bool> > exp1 = x => x.Id > 1;
                    }

                    if (true) //过滤B
                    {
                        Expression <Func <People, bool> > exp2 = x => x.Age > 10;
                    }

                    // 都过滤
                    Expression <Func <People, bool> > exp3 = x => x.Age > 10 && x.Id > 1;
                    {
                        // 表达式链接
                        Expression <Func <People, bool> > lambda1 = x => x.Age > 5;
                        Expression <Func <People, bool> > lambda2 = x => x.Id > 5;
                        Expression <Func <People, bool> > lambda3 = lambda1.And(lambda2);
                        Expression <Func <People, bool> > lambda4 = lambda1.Or(lambda2);
                        Expression <Func <People, bool> > lambda5 = lambda1.Not();

                        Do1(lambda3);
                    }
                    // Copy People 属性
                    {
                        {
                            // 写死了 只能为这两种类型服务, 性能最好因为硬编码
                            People people = new People()
                            {
                                Id   = 1,
                                Name = "Ivan",
                                Age  = 32
                            };

                            PeopleCopy peopleCopy = new PeopleCopy()
                            {
                                Id   = people.Id,
                                Name = people.Name,
                                Age  = people.Age
                            };
                        }

                        {
                            // 利用反射: 不同类型都能实现
                            People people = new People()
                            {
                                Id   = 1,
                                Name = "Ivan",
                                Age  = 32
                            };
                            var result = ReflectionMapper.Trans <People, PeopleCopy>(people);
                        }
                        {
                            People people = new People()
                            {
                                Id   = 1,
                                Name = "Ivan",
                                Age  = 32
                            };
                            //序列化器

                            var result = SerializeMapper.Trans <People, PeopleCopy>(people);
                        }
                        {
                            People people = new People()
                            {
                                Id   = 1,
                                Name = "Ivan",
                                Age  = 32
                            };
                            //1. 通用 2. 性能要高
                            // 能不能动态的生成硬编码,缓存起来
                            Expression <Func <People, PeopleCopy> > lambda = p => new PeopleCopy()
                            {
                                Id   = p.Id,
                                Name = p.Name,
                                Age  = p.Age
                            };

                            ExpressionMapper.Trans <People, PeopleCopy>(people);
                        }
                    }
                }
            }
        }