》》》可以借助 LINQPad工具
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;namespace EFDemo
{public class Product{public string Product_Name { get; set; }public int Product_Price { get; set; }}class Program{static void Main(string[] args){List<Product> prolist = new List<Product>() {new Product(){ Product_Name="苹果手机",Product_Price=5999},new Product(){ Product_Name="华为手机",Product_Price=4999},new Product(){ Product_Name="华为手机",Product_Price=6999},new Product(){ Product_Name="苹果手机",Product_Price=9999}};var result1= prolist.Where(c =>{ return c.Product_Name == "苹果手机" && c.Product_Price > 6000; });foreach (var r in result1){Console.WriteLine($"产品名称:{r.Product_Name} 价格:{r.Product_Price}");}var item=Expression.Parameter(typeof(Product), "item");var item_name = Expression.Property(item, "Product_Name");var item_price= Expression.Property(item, "Product_Price");var query_Name = Expression.Constant("苹果手机");var query_Price = Expression.Constant(6000);var c1 = Expression.Equal(item_name, query_Name);var c2 = Expression.GreaterThan(item_price, query_Price);var cc = Expression.And(c1, c2);var lambda_expression = Expression.Lambda<Func<Product, bool>>(cc, item);var reuslt = lambda_expression.Compile();Console.WriteLine(lambda_expression.ToString());var res = prolist.Where(reuslt);foreach (var r in res){Console.WriteLine($"产品名称:{r.Product_Name} 价格:{r.Product_Price}");}Console.ReadKey();}}
}
》》》表达式树 编译之后 才是委托
利用表达式树 对象的映射
》》》定义一个泛型静态类 ExpressionMapper<Tin ,Tout>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;namespace EFDemo
{public class ExpressionMapper<Tin ,Tout>{private static Func<Tin, Tout> _Func = null;static ExpressionMapper(){ParameterExpression paramExp = Expression.Parameter(typeof(Tin), "p");List<MemberBinding> memberBindingList = new List<MemberBinding>();//绑定属性foreach (var item in typeof(Tout).GetProperties()){// 比如p.Product_IDMemberExpression member = Expression.Property(paramExp, typeof(Tin).GetProperty(item.Name)); //Product_ID = p.Product_ID MemberBinding memberBinding = Expression.Bind(item,member); memberBindingList.Add(memberBinding);}//绑定字段foreach (var item in typeof(Tout).GetFields()){MemberExpression member = Expression.Field(paramExp, typeof(Tin).GetField(item.Name));MemberBinding memberBinding = Expression.Bind(item, member);memberBindingList.Add(memberBinding);}//创建新对象并初始化 //new Good() {Product_ID= p.Product_ID, Product_Price= p.Product_Price}MemberInitExpression memberInitExp = Expression.MemberInit(Expression.New(typeof(Tout)),memberBindingList.ToArray());//p=>new Good() {Product_ID= p.Product_ID, Product_Price= p.Product_Price}Expression<Func<Tin, Tout>> funcExp = Expression.Lambda<Func<Tin, Tout>>(memberInitExp, new ParameterExpression[] { paramExp });_Func = funcExp.Compile();}public static Tout Mapper(Tin t){return _Func(t);}}
}
》》》 使用.netFramwork框架自带的AutoMapper,首先我们要nuget添加引用AutoMapper即可直接使用,具体代码为:
using AutoMapper;namespace ExpressionDemo.MappingExtend
{public class AutoMapperTest{public static TOut Trans<TIn, TOut>(TIn tIn){return Mapper.Instance.Map<TOut>(tIn);}}
}
》》》利用反射
/// <summary>/// 反射/// </summary>/// <typeparam name="TIn"></typeparam>/// <typeparam name="TOut"></typeparam>/// <param name="tIn"></param>/// <returns></returns>public static TOut Trans<TIn, TOut>(TIn tIn){TOut tOut = Activator.CreateInstance<TOut>();foreach (var itemOut in tOut.GetType().GetProperties()){var propIn = tIn.GetType().GetProperty(itemOut.Name);itemOut.SetValue(tOut, propIn.GetValue(tIn));}foreach (var itemOut in tOut.GetType().GetFields()){var fieldIn = tIn.GetType().GetField(itemOut.Name);itemOut.SetValue(tOut, fieldIn.GetValue(tIn));}return tOut;}
》》》 使用序列化和反序列化来完成对象属性映射:
/// <summary>/// 使用第三方序列化反序列化工具/// /// 还有automapper/// </summary>public class SerializeMapper{/// <summary>/// 序列化反序列化方式/// </summary>/// <typeparam name="TIn"></typeparam>/// <typeparam name="TOut"></typeparam>public static TOut Trans<TIn, TOut>(TIn tIn){return JsonConvert.DeserializeObject<TOut>(JsonConvert.SerializeObject(tIn));}}
》》》用lambda 生成 表达式
Lambda使用lambda表达声明表达式目录树的时候注意不能有{},即:
Expression<Func<int, int, int>> exp1 = (m, n) =>{return m * n + 2;};//不能有语句体 只能是一行,不能有大括号
internal static class SqlOperator{internal static string ToSqlOperator(this ExpressionType type){switch (type){case (ExpressionType.AndAlso):case (ExpressionType.And):return "AND";case (ExpressionType.OrElse):case (ExpressionType.Or):return "OR";case (ExpressionType.Not):return "NOT";case (ExpressionType.NotEqual):return "<>";case ExpressionType.GreaterThan:return ">";case ExpressionType.GreaterThanOrEqual:return ">=";case ExpressionType.LessThan:return "<";case ExpressionType.LessThanOrEqual:return "<=";case (ExpressionType.Equal):return "=";case ExpressionType.Subtract:return "-";default:throw new Exception("不支持该方法");}}}public class CustomVisitor : ExpressionVisitor{private Stack<string> _StringStack = new Stack<string>();public string Condition(){string condition = string.Concat(this._StringStack.ToArray());this._StringStack.Clear();return condition;}/// <summary>/// 如果是二元表达式/// </summary>/// <param name="node"></param>/// <returns></returns>protected override Expression VisitBinary(BinaryExpression node){if (node == null) throw new ArgumentNullException("BinaryExpression");this._StringStack.Push(")");base.Visit(node.Right);//解析右边this._StringStack.Push(" " + node.NodeType.ToSqlOperator() + " ");base.Visit(node.Left);//解析左边this._StringStack.Push("(");return node;}/// <summary>/// /// </summary>/// <param name="node"></param>/// <returns></returns>protected override Expression VisitMember(MemberExpression node){if (node == null) throw new ArgumentNullException("MemberExpression");this._StringStack.Push(" [" + node.Member.Name + "] ");return node;}/// <summary>/// 常量表达式/// </summary>/// <param name="node"></param>/// <returns></returns>protected override Expression VisitConstant(ConstantExpression node){if (node == null) throw new ArgumentNullException("ConstantExpression");this._StringStack.Push(" '" + node.Value + "' ");return node;}/// <summary>/// 方法表达式/// </summary>/// <param name="m"></param>/// <returns></returns>protected override Expression VisitMethodCall(MethodCallExpression m){if (m == null) throw new ArgumentNullException("MethodCallExpression");string format;switch (m.Method.Name){case "StartsWith":format = "({0} LIKE {1}+'%')";break;case "Contains":format = "({0} LIKE '%'+{1}+'%')";break;case "EndsWith":format = "({0} LIKE '%'+{1})";break;default:throw new NotSupportedException(m.NodeType + " is not supported!");}this.Visit(m.Object);this.Visit(m.Arguments[0]);string right = this._StringStack.Pop();string left = this._StringStack.Pop();this._StringStack.Push(String.Format(format, left, right));return m;}}
Expression<Func<People, bool>> lambda = x => x.Age > 5 && x.Name == "A" || x.Id > 5;CustomVisitor vistor = new CustomVisitor();vistor.Visit(lambda);Console.WriteLine(vistor.Condition());